gpt4 book ai didi

c# - LINQ "' s' is not in scope"when creating where clause dynamically

转载 作者:行者123 更新时间:2023-11-30 15:05:56 25 4
gpt4 key购买 nike

所以,我得到了标题中的错误。我将直接跳转到相关代码。首先,手动创建 where 语句(有效),然后动态创建无效。两者都创建相同的查询表达式。

首先,使用这两种方法生成的 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
} );

唯一不同的是,在第二个片段中,我动态创建了 lambda 表达式。我已经注意到它在第二个片段中失败的地方。

使用调试器,我可以看到数据的 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);

这个.PE是:

public ParameterExpression PE
{
get
{
return Expression.Parameter(typeof(SalesData), "s");
}
}

最佳答案

来自 C# 之父 Anders Hejlsberg:

Parameters are referenced in expressions through their object identity, not by comparing their names. In fact, from an expression tree's point of view, the name of a parameter is purely informational. The reason for this design is the same reason that types are referenced through their System.Type objects and not their names--expression trees are fully bound and are not in the business of implementing name lookup rules (which may differ from language to language).

From MSDN Forums

总而言之,filter.Predicate 的值为 {(s.Count > 500)} 但这并不意味着 s 在这里有意义,因为它与初始 LINQ 表达式共享一个名称。

关于c# - LINQ "' s' is not in scope"when creating where clause dynamically,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8521516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com