Estoy intentando construir una expresión lambda que se combinará con otras en un árbol de expresiones bastante grande para filtrar. Esto funciona bien hasta que necesite filtrar por una propiedad de sub colección.Crear un árbol de expresiones dinámicas para filtrar en una propiedad de la colección
¿Cómo se genera una expresión Lambda que se filtrará utilizando Any() en una propiedad de una colección que es una propiedad del objeto raíz?
Ejemplo:
CurrentDataSource.Offices.Where(o => o.base_Trades.Any(t => t.Name == "test"))
Esto es cómo iba a construir la expresión de forma estática, pero tengo que construirlo de forma dinámica. Perdón por la confusion.
Editar: Aquí hay un fragmento de cómo manejar las expresiones menos complicados:
IQueryable<Office> officeQuery = CurrentDataSource.Offices.AsQueryable<Office>();
ParameterExpression pe = Expression.Parameter(typeof(Office), "Office");
ParameterExpression tpe = Expression.Parameter(typeof(Trades), "Trades");
Expression SimpleWhere = null;
Expression ComplexWhere = null;
foreach (ServerSideFilterObject fo in ssfo)
{
SimpleWhere = null;
foreach (String value in fo.FilterValues)
{
if (!CollectionProperties.Contains(fo.PropertyName))
{
//Handle singleton lambda logic here.
Expression left = Expression.Property(pe, typeof(Office).GetProperty(fo.PropertyName));
Expression right = Expression.Constant(value);
if (SimpleWhere == null)
{
SimpleWhere = Expression.Equal(left, right);
}
else
{
Expression e1 = Expression.Equal(left, right);
SimpleWhere = Expression.Or(SimpleWhere, e1);
}
}
else
{
//handle inner Collection lambda logic here.
Expression left = Expression.Property(tpe, typeof(Trades).GetProperty("Name"));
Expression right = Expression.Constant(value);
Expression InnerLambda = Expression.Equal(left, right);
//Problem area.
Expression OfficeAndProperty = Expression.Property(pe, typeof(Office).GetProperty(fo.PropertyName));
Expression OuterLambda = Expression.Call(OfficeAndProperty, typeof(Trades).GetMethod("Any", new Type[] { typeof(Expression) }),InnerLambda);
if (SimpleWhere == null)
SimpleWhere = OuterLambda;
else
SimpleWhere = Expression.Or(SimpleWhere, OuterLambda);
}
}
if (ComplexWhere == null)
ComplexWhere = SimpleWhere;
else
ComplexWhere = Expression.And(ComplexWhere, SimpleWhere);
}
MethodCallExpression whereCallExpression = Expression.Call(typeof(Queryable), "Where", new Type[] { officeQuery.ElementType }, officeQuery.Expression, Expression.Lambda<Func<Office, bool>>(ComplexWhere, new ParameterExpression[] { pe }));
results = officeQuery.Provider.CreateQuery<Office>(whereCallExpression);
¿Estás preguntando cómo construir un árbol de expresiones? – SLaks
No estoy seguro de cómo funciona la jerarquía en su ejemplo. ¿Puedes elaborar un poco más sobre eso? ¿Las oficinas son la raíz y luego cada oficina tiene una colección de oficios? ¿Y desea filtrar el nombre del comercio? El filtro es donde estoy un poco perdido. Lo siento. –
No, no estoy seguro de la sintaxis utilizada para construir una expresión con una llamada al método interno y una expresión para un parámetro. En este caso, aparece un error que indica que Any() no se puede encontrar porque mis parámetros no coinciden con la definición. En este caso, no estoy seguro de si es porque estoy sintaxis o si Any() no es compatible con la forma en que lo estoy usando. – George