我想创建类似这样的 lambda
user => user.Address == address
但不是编译一个,我想返回LambdaExpression
如果 lambda 像这样取常量
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))
编辑:澄清我的问题:How build the right Expression
to generate the first lambda?
更新:这是不可能的,因为EF does not support non-scalar variable
我按照建议将 lambda 更改为 user => user.AddressId == addressId
here .问题在于如何从已知的导航属性 Address
中获取 AddressId
FK PropertyInfo
。
最佳答案
您不能在变量上动态生成闭包(您不能在其上下文之外延长变量的生命周期),因为这是编译器的一个技巧(它会重写您的代码来执行此操作)。
如果您不需要闭包但需要额外的参数,那么您可以向表达式添加额外的参数。
你可以
Expression<Func<string>> myExpr = () => address;
现在您的地址周围有一个表达式。现在您只需要组合这两个表达式。
您必须将方法更改为:
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 }
);
}
关于c# - 创建包含外部变量的 LambdaExpression,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17991079/