Reputation: 357
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.
Upvotes: 0
Views: 990
Reputation: 16796
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.)
Upvotes: 3