【发布时间】:2012-02-17 04:07:52
【问题描述】:
我正在尝试构建一个 lambda 表达式,它将与其他表达式组合成一个相当大的表达式树进行过滤。在我需要按子集合属性过滤之前,这工作正常。
如何构建一个 Lambda 表达式,该表达式将使用 Any() 对作为根对象的属性的集合的属性进行过滤?
例子:
CurrentDataSource.Offices.Where(o => o.base_Trades.Any(t => t.Name == "test"))
这就是我静态构建表达式的方式,但我需要动态构建它。很抱歉造成混乱。
编辑:这是我如何处理不太复杂的表达式的 sn-p:
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);
【问题讨论】:
-
你是在问如何构建表达式树?
-
我不确定层次结构在您的示例中是如何工作的。你能详细说明一下吗?办公室是根,然后每个办公室都有一个交易集合吗?你想过滤交易的名称??过滤器是我有点迷路的地方。对不起。
-
不,我只是不确定用于构建具有内部方法调用和参数表达式的表达式的语法。在这种情况下,我收到一条错误消息,指出找不到 Any(),因为我的参数与定义不匹配。在这种情况下,我不确定这是因为我对语法不感兴趣,还是我使用它的方式不支持 Any()。
-
就层次结构而言:办公室是根,每个办公室都有一个交易集合。我正在尝试根据集合中每个交易对象的 Name 属性过滤集合。
标签: c# wcf entity-framework lambda filtering