创建包含外部变量的LambdaExpression

我想创建像这样的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 } ); } 

如何让这个方法接受变量address来自lambda表达式之外的范围?

 var addressPropertyName = "Address"; var address = new Address() {...}; var q = Repo.GetQuery().Where(PropertyEqual(typeof(User), addressPropertyName, address)) 

编辑:澄清我的问题:如何构建正确的Expression来生成第一个lambda?

更新:这是不可能的,因为EF不支持非标量变量

我按照此处的建议将lambda更改为user => user.AddressId == addressId 。 如何从已知的导航属性Address获取AddressId FK PropertyInfo

您无法动态生成变量的闭包(您无法在其上下文之外扩展变量的生命周期),因为这是编译器的一个技巧(重写代码来执行此操作)。

如果您不想要闭包但需要其他参数,则可以向表达式添加其他参数。

你可以

 Expression> myExpr = () => address; 

现在你有一个关闭你的地址的表达式。 现在你只需要组合这两个表达式。

您必须将方法更改为:

 public static LambdaExpression PropertyEqual(Type tEntityType, string propertyName, Expression> 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 } ); }