11
I’m trying to build a Lambda Expression that’s a little complex and I’m having difficulties.
The goal is this expression:
items = items.Where(x => sValues.Any(y => x.Contract_Rates.Select(z => z.CostCenterId).Contains(y)));
However, in RunTime
, i don’t know the name of the list that in the example is Contract_Rates
, the point is that I need to scan the collections of an object, I already have a method that fills the variable Collections
(displayed in the code below) and check if this is a collection that implements IHasCostCenter
, positive case, carry out the Lambda Expression
quoted.
What I’ve got so far is:
var sValues = User.CostCenters.Select(x => x.CostCenterId).ToList();
ParameterExpression Parameter = Expression.Parameter(typeof(Contrato), "x");
foreach (var item in Collections.Select(x => x).Where(x => x.GetInterfaces().Any(y => y == typeof(IHasCostCenter))))
{
// Obtenho o nome da lista (i.e. 'Contract_Rates')
var PropertyName = typeof(T).GetProperties().FirstOrDefault(x => x.Name.Contains(item.Name)).Name;
Expression Property = Expression.Property(Parameter, typeof(T).GetProperty(PropertyName));
LambdaExpression Column = Expression.Lambda(Property, Parameter);
Expression Select = Expression.Call(
typeof(Queryable),
"Select",
new Type[] { items.ElementType, Column.Body.Type },
items.Expression,
Column);
Expression Contains = Expression.Call(
typeof(Enumerable),
"Contains",
new[] { sValuesType },
Expression.Constant(sValues, sValues.GetType()),
Select);
MethodCallExpression Where = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { items.ElementType },
items.Expression,
Expression.Lambda(Contains, Parameter));
items = items.Provider.CreateQuery<T>(Where);
However I cannot correctly develop how I get the expression SELECT x.Contract_Rates.Select(y => y.CostCenterId)
and how I get the expression ANY sValues.Any(y => x.Contrato_Rateios.Select(z => z.CentroCustoId).Contains(y))
Any help will be appreciated.
Why you necessarily need to use lambda Expressions?
– Leonel Sanches da Silva
I can’t use it
Lambda
normally because I don’t know the name of the attributes, I can’t useReflection
other than forLambda Expression
. Nor can I convert the object during the use ofLambda
(forIHasCostCenter
, for example) because the object after converted generates error when returning to the entityT
. Can you see some other way?– e.leal.br
It seems to me a code too complicated for what you want to do. Maybe understanding the issue of a macro scope I can help you better.
– Leonel Sanches da Silva
Thank you for your attention @Ciganomorrisonmendez. The situation is as follows: Imagine that each user has a list of Costcenter (
sValues
). Based on this list I need to filter the tuples of the classes that he can see, and this can only happen if the entity implements Ihascostcenter, because not all classes need this filter, While if the parent class does not implement Ihascostcenter but some daughter property (or list, in this case) implement, I also need to filter the parent class tuples by the daughters. Got it?– e.leal.br
Don’t you think it’s too complicated to filter the visibility of a record using an interface? I would use something other than reflection for that.
– Leonel Sanches da Silva
this question is as active. It still needs an answer?
– Fernando Mondo
Hello @Fernandomondo, the issue has not yet been resolved, I am particularly using an approach in which it is necessary to name the property as I have not found solution to this specific way.
– e.leal.br
Your first expression can be simplified. I know it doesn’t answer, but sometimes it can help in the solution.
items = items.Where(x => sValues.Any(y => x.Contract_Rates.Any(z => z.CostCenterId == y));
– Thiago Lunardi