C# 林奇';s';“不在范围内”;动态创建where子句时

C# 林奇';s';“不在范围内”;动态创建where子句时,c#,linq-to-sql,lambda,expression-trees,C#,Linq To Sql,Lambda,Expression Trees,所以,我得到了标题中的错误。我将直接进入相关代码。首先,手动创建where语句(该语句有效),然后是动态创建(该语句无效)。两者都创建相同的queryExpression 首先,使用两种方法生成的queryExpression: {Table(Products).Select (s => new SalesData() { ProductID = s.ProductID, StoreName = s.StoreName, Count = s.Count }).

所以,我得到了标题中的错误。我将直接进入相关代码。首先,手动创建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
                                 } );
这是:

public ParameterExpression PE
{
    get
    {
        return Expression.Parameter(typeof(SalesData), "s");
    }
}
出自C#之父安德斯·海尔斯伯格:

表达式中的参数是通过其对象标识引用的,而不是通过比较其名称来引用的。事实上,从表达式树的角度来看,参数的名称纯粹是信息性的。这种设计的原因与类型通过其System.Type对象而不是名称引用的原因相同——表达式树是完全绑定的,不用于实现名称查找规则(不同语言可能不同)


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

我能够解决我的问题,这要感谢此页面上的对话框和使用


对于我正在尝试做的事情,可以在上找到更好的方法。这对我来说更好,因为我需要动态确定字段和值,并允许分组(使用此方法更容易)。

过滤器的类型和值是什么。谓词是什么?还要注意的是,仅仅因为两个lambda参数被调用相同,从表达式的角度来看,它们是不相等的…filter.Predicate是类型表达式,调试器说值是{(s.Count>500)}看看filter.Predicate在哪里设置了它的值。关于它为什么不起作用的所有信息现在都在这个页面上,但不是为什么它被设置为一开始就不起作用。@JonHanna我更新了我的问题,包括filter.Predicate如何获取它的值,以及filter.PE
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);
public ParameterExpression PE
{
    get
    {
        return Expression.Parameter(typeof(SalesData), "s");
    }
}