C# 并与参数';foo';未在指定的LINQ to Entities查询表达式中绑定
我有一个实体C# 并与参数';foo';未在指定的LINQ to Entities查询表达式中绑定,c#,linq,entity-framework,linq-expressions,C#,Linq,Entity Framework,Linq Expressions,我有一个实体 public class Foo { public int Id { get; set; } public string Name { get; set; } public string Code { get; set; } } 我想创建自己的表达式谓词。为此,我创建了一个接受属性名和值的方法 private static Expression<Func<Foo, bool>> Condition(string pName, obj
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
public string Code { get; set; }
}
我想创建自己的表达式谓词。为此,我创建了一个接受属性名和值的方法
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;
}
但当我试图通过以下方式组合两个条件时,它抛出异常
参数“foo”未在指定的LINQ to实体中绑定
查询表达式
使用(var db=new MyEntities())
{
var cond1=条件(“名称”、“foo”);
var cond2=条件(“代码”、“条形”);
var body=表达式.AndAlso(cond1.body,cond2.body);
var谓词=Expression.Lambda(body,cond1.Parameters[0]);
var foos=db.foos.Where(谓词).ToArray();//异常
}
请告诉我。问题是LINQ表达式中的
参数表达式
是通过引用相等来标识的,但是两个参数
对象是不同的引用。(参数表达式中的名称
仅用于调试目的)
(如果您重新阅读上面提到的文章,它会说您尝试的方法只有在两个lambda都定义在同一个ParameterExpression
对象上时才有效)
在这个阶段,您有两个很大的可能性:要么为
条件
函数定义一种方法来接受参数表达式
对象,要么创建一个表达式访问者
,用另一个对象替换原来的参数表达式
。(当然,考虑到您想要执行和
,您也可以将两个Where
子句链接起来,但这不太一般。)问题是,LINQ表达式中的参数表达式
是通过引用相等来标识的,但两个参数
对象是不同的引用。(参数表达式中的名称
仅用于调试目的)
(如果您重新阅读上面提到的文章,它会说您尝试的方法只有在两个lambda都定义在同一个ParameterExpression
对象上时才有效)
在这个阶段,您有两个很大的可能性:要么为
条件
函数定义一种方法来接受参数表达式
对象,要么创建一个表达式访问者
,用另一个对象替换原来的参数表达式
。(当然,考虑到您想要执行和
,您也可以将两个Where
子句链接起来,但这不太一般。)问题是,LINQ表达式中的参数表达式
是通过引用相等来标识的,但两个参数
对象是不同的引用。(参数表达式中的名称
仅用于调试目的)
(如果您重新阅读上面提到的文章,它会说您尝试的方法只有在两个lambda都定义在同一个ParameterExpression
对象上时才有效)
在这个阶段,您有两个很大的可能性:要么为
条件
函数定义一种方法来接受参数表达式
对象,要么创建一个表达式访问者
,用另一个对象替换原来的参数表达式
。(当然,考虑到您想要执行和
,您也可以将两个Where
子句链接起来,但这不太一般。)问题是,LINQ表达式中的参数表达式
是通过引用相等来标识的,但两个参数
对象是不同的引用。(参数表达式中的名称
仅用于调试目的)
(如果您重新阅读上面提到的文章,它会说您尝试的方法只有在两个lambda都定义在同一个ParameterExpression
对象上时才有效)
在这个阶段,您有两个很大的可能性:要么为
条件
函数定义一种方法来接受参数表达式
对象,要么创建一个表达式访问者
,用另一个对象替换原来的参数表达式
。(当然,考虑到你想做一个和一个,你也可以把两个Where
子句链接起来,但这不太一般。)谢谢,所以你建议把表达式参数作为方法参数?我现在就试试。@tsuta:这是一种方法。另一种方法是用一个每次都重用相同参数对象的对象封装lambda表达式构建过程。使用ExpressionVisitor
更为复杂,但如果您不控制创建的Expression
对象,这将是主要的方法。感谢您的解释,我仍在学习Expression,并且对它如何构建谓词非常感兴趣,稍后我将尝试使用Expression visitor,但现在它涵盖了我的需求,因为我可以完全控制自己的表达式。谢谢,所以你建议将表达式参数作为方法参数去掉?我现在就试试。@tsuta:这是一种方法。另一种方法是用一个每次都重用相同参数对象的对象封装lambda表达式构建过程。使用ExpressionVisitor
更为复杂,但如果您不控制创建的Expression
对象,这将是主要的方法。感谢您的解释,我仍在学习Expression,并且对它如何构建谓词非常感兴趣,稍后我将尝试使用Expression visitor,但现在它涵盖了我的需求,因为我可以完全控制自己的表达式。谢谢,所以你建议将表达式参数作为方法参数去掉?我现在就试试。@tsuta:这是一种方法。另一个
using (var db = new MyEntities())
{
var predicate = Condition("Name", "foo");
var foos = db.Foos.Where(predicate).ToArray();
}
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
}