Sto provando a creare un'espressione lambda che verrà combinata con altri in un albero di espressioni piuttosto grande per il filtro. Funziona bene fino a quando non ho bisogno di filtrare da una proprietà di sub-raccolta.Creazione di un albero di espressioni dinamiche per filtrare su una proprietà di raccolta
Come si costruisce un'espressione Lambda che filtra utilizzando Any() su una proprietà di una raccolta che è una proprietà dell'oggetto root?
Esempio:
CurrentDataSource.Offices.Where(o => o.base_Trades.Any(t => t.Name == "test"))
Questo è come vorrei costruire l'espressione in modo statico, ma ho bisogno di costruire in modo dinamico. Dispiace per la confusione.
Edit: Ecco un frammento di come gestire le espressioni meno complicate:
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);
Stai chiedendo come costruire un albero di espressioni? – SLaks
Non sono sicuro di come la gerarchia funzioni nel tuo esempio. Puoi approfondire un po 'su questo? Uffici è la radice e quindi ogni ufficio ha una raccolta di mestieri? E vuoi filtrare il nome del trade ?? Il filtro è dove sono un po 'perso. Scusate. –
No, non sono sicuro della sintassi utilizzata per creare un'espressione con una chiamata di metodo interna e un'espressione per un parametro. In questo caso, viene visualizzato un errore che indica che Any() non può essere trovato perché i miei parametri non corrispondono alla definizione. In questo caso non sono sicuro che sia perché non sono sintonizzato sulla sintassi o se Any() non è supportato nel modo in cui lo sto usando. – George