C# 创建包含外部变量的LambdaExpression
我想创建类似这样的lambdaC# 创建包含外部变量的LambdaExpression,c#,linq,entity-framework,lambda,entity-framework-5,C#,Linq,Entity Framework,Lambda,Entity Framework 5,我想创建类似这样的lambda user => user.Address == address user => user.Age == 50 但是不是编译的,我想返回LambdaExpression 如果lambda像这样取常数 user => user.Address == address user => user.Age == 50 然后我可以用这个方法 public static LambdaExpression PropertyEqual(Type
user => user.Address == address
user => user.Age == 50
但是不是编译的,我想返回LambdaExpression
如果lambda像这样取常数
user => user.Address == address
user => user.Age == 50
然后我可以用这个方法
public static LambdaExpression PropertyEqual(Type tEntityType, string propertyName, object value)
{
// entity => entity.PropName == const
var itemParameter = Expression.Parameter(tEntityType, "entity");
return Expression.Lambda
(
Expression.Equal
(
Expression.Property
(
itemParameter,
propertyName
),
Expression.Constant(value) // Tried to replace this with Expression.Parameter or Expression.Variable but no luck
),
new[] { itemParameter }
);
}
如何使此方法接受来自lambda表达式范围之外的变量address
var addressPropertyName = "Address";
var address = new Address() {...};
var q = Repo.GetQuery().Where(PropertyEqual(typeof(User), addressPropertyName, address))
编辑:澄清我的问题:如何构建正确的表达式来生成第一个lambda
更新:这是不可能的,因为
我按照建议将lambda更改为user=>user.AddressId==AddressId
。如何从已知的导航属性Address中获取AddressId
FKPropertyInfo
只是个问题,你不能动态地在变量上生成闭包(你不能在它的上下文之外延长变量的生存期),因为这是编译器的一个技巧(重写你的代码来完成)
如果不需要闭包,但需要附加参数,则可以向表达式中添加附加参数
你可以
Expression<Func<string>> myExpr = () => address;
表达式myExpr=()=>地址;
现在,您的地址周围有一个表达式。现在您只需将这两个表达式组合起来
您必须将方法更改为:
public static LambdaExpression PropertyEqual<T>(Type tEntityType, string propertyName, Expression<Func<T>> getValue)
{
// entity => entity.PropName == const
var itemParameter = Expression.Parameter(tEntityType, "entity");
return Expression.Lambda
(
Expression.Equal
(
Expression.Property
(
itemParameter,
propertyName
),
Expression.Invoke(getValue) // You could directly use getValue.Body instead of Expression.Invoke(getValue)
),
new[] { itemParameter }
);
}
公共静态LambdaExpression propertyqual(类型tEntityType、字符串propertyName、表达式getValue)
{
//entity=>entity.PropName==const
var itemParameter=Expression.Parameter(tEntityType,“实体”);
返回表达式.Lambda
(
表达式。相等
(
表达式.属性
(
itemParameter,
属性名称
),
Expression.Invoke(getValue)//可以直接使用getValue.Body而不是Expression.Invoke(getValue)
),
新[]{itemParameter}
);
}
添加附加参数将变成类似于(user,address)=>user.address==address
而不是user=>user.address==address
,它具有不同的返回表达式expression
而不是expression
您无法获得“引用”将其添加到变量中,并将其放入表达式中
<代码>类型引用
和表达式树不“兼容”。您可以做的是预先创建一个指向您的地址的表达式,然后组成两个表达式树。关闭将由编译器完成。很抱歉,如何组合这两个表达式并返回LambdaExpression
<代码>表达式。Lambda(…)只接受一个表达式
正文。我得到“调用
在LINQ to Entities中不受支持”&如果使用getValue.body,我得到错误“无法创建常量值…”。我想是因为address
变量是一个EF实体,而不是值类型。@callmelan那么是的,我想你的问题是你不能直接这样做(正如你提供的链接所说)。您可以比较它们的.ID
。