【发布时间】:2011-12-15 14:20:54
【问题描述】:
所以,我得到了标题中的错误。我将直接进入相关代码。首先,手动创建 where 语句(有效),然后动态创建无效。两者都创建相同的 queryExpression。
首先,使用这两种方法生成的queryExpression:
{Table(Products).Select
(s => new SalesData() {
ProductID = s.ProductID,
StoreName = s.StoreName,
Count = s.Count
}).Where(s => (s.Count > 500))}
现在,确实有效的手动方法:
IQueryable<SalesData> data = ( from s in sales.Products
select new SalesData
{
ProductID = s.ProductID,
StoreName = s.StoreName,
Count = s.Count
} ).AsQueryable<SalesData>();
data = data.Where(s => s.Count > 500);
this.dataGridView1.DataSource = null;
this.dataGridView1.DataSource = (from d in data
select new
{
d.ProductID,
d.StoreName,
d.Count
} );
这按预期工作;我的 DataGridView 填充了数据。
现在,动态创建 where 子句:
IQueryable<SalesData> data = ( from s in sales.Products
select new SalesData
{
ProductID = s.ProductID,
StoreName = s.StoreName,
Count = s.Count
} ).AsQueryable<SalesData>();
if (this.filter.Predicate != null)
{
Expression<Func<SalesData, bool>> lambda =
Expression.Lambda<Func<SalesData, bool>>(this.filter.Predicate,
new ParameterExpression[] { this.filter.PE });
data = data.Where(lambda);
}
this.dataGridView1.DataSource = null;
this.dataGridView1.DataSource = (from d in data <---- fails here
select new
{
d.ProductID,
d.StoreName,
d.Count
} );
唯一不同的是,在第二个 sn-p 中,我动态地创建了 lambda 表达式。我已经注意到它在第二个 sn-p 中失败的地方。
使用调试器,我可以看到数据的 queryExpression,这两种方法都是一样的,所以我认为我的问题不在于我的实际表达式创建。如果需要该代码,我可以在这里发布。
我的问题是,我做错了什么以及如何解决?
编辑: 这是给出 filter.Predicate 其值的函数:
public static Expression GetPredicate(List<FilterItem> itemList, ParameterExpression pe)
{
List<Expression> expressions = new List<Expression>();
List<string> combiners = new List<string>();
foreach (FilterItem item in itemList)
{
Expression left = Expression.PropertyOrField(pe, item.Field);
Expression right = Expression.Constant(Convert.ToInt32(item.Value), typeof(int));
expressions.Add(Expression.GreaterThan(left, right));
combiners.Add(item.Combiner);
}
int expressionCount = expressions.Count();
Expression predicateBody = expressions[0];
if (expressionCount > 1)
{
for (int x = 1; x <= expressionCount; x++)
{
switch (combiners[x - 1])
{
case "AND":
predicateBody = Expression.And(predicateBody, expressions[x]);
break;
case "OR":
predicateBody = Expression.Or(predicateBody, expressions[x]);
break;
default:
break;
}
}
}
return predicateBody;
}
我有内部过滤器:
this.Predicate = BuildPredicate.GetPredicate(this.filterList, this.PE);
this.PE 是:
public ParameterExpression PE
{
get
{
return Expression.Parameter(typeof(SalesData), "s");
}
}
【问题讨论】:
-
filter.Predicate的类型和值是什么?另请注意,仅仅因为两个 lambda 参数被称为相同,从表达式的角度来看它们并不相等...... -
filter.Predicate 是 Expression 类型,调试器说该值为 {(s.Count > 500)}
-
filter.Predicate 在哪里设置了它的值。所有关于它为什么不起作用的信息现在都在这个页面上,但不是为什么它被设置为一开始就不起作用的东西。
-
@JonHanna 我更新了我的问题,包括 filter.Predicate 如何获取它的值,以及 filter.PE
标签: c# linq-to-sql lambda expression-trees