Combining AndAlso The parameter 'foo' was

2019-09-15 23:26发布

I have an entity.

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
}

I want to create my own expression predicate. For that I have created a method that accepts property name and the value.

private static Expression<Func<Foo, bool>> Condition(string pName, object value)
{
    var pe = Expression.Parameter(typeof(Foo), "foo");
    var left = Expression.Property(pe, pName);
    var right = Expression.Constant(value);
    var equal = Expression.Equal(left, right);
    var predicate = Expression.Lambda<Func<Foo, bool>>(equal, pe);
    return predicate;
}

This is the predicate which works fine for a single condition.

using (var db = new MyEntities())
{
    var predicate = Condition("Name", "foo");
    var foos = db.Foos.Where(predicate).ToArray();
}

But when I tried to combine two conditions by following this post, it throws exception.

The parameter 'foo' was not bound in the specified LINQ to Entities query expression.

using (var db = new MyEntities())
{
    var cond1 = Condition("Name", "foo");
    var cond2 = Condition("Code", "bar");
    var body = Expression.AndAlso(cond1.Body, cond2.Body);
    var predicate = Expression.Lambda<Func<Foo,bool>>(body, cond1.Parameters[0]);
    var foos = db.Foos.Where(predicate).ToArray(); // exception
}

Please enlighten me.

1条回答
相关推荐>>
2楼-- · 2019-09-15 23:55

The problem is that ParameterExpression in LINQ expressions is identified by reference equality, but the two Parameter objects are different references. (The name in ParameterExpression only exists for debugging purposes).

(If you reread the mentioned post, it says that the method that you tried would only work if both lambdas are defined on the same ParameterExpression object).

You have two big possibilities at this stage: either you define a way for the Condition function to accept a ParameterExpression object, or you create an ExpressionVisitor that will replace the original ParameterExpression with another. (Of course, given that you want to do an AndAlso, you could also conceivably chain two Where clauses, but that is less general.)

查看更多
登录 后发表回答