Create LambdaExpression that contain external variable
c#, entity-framework, entity-framework-5, lambda, linq
Solution
You can't dynamically generate a closure on a variable (you can't extend the lifetime of a variable outside its context) because this is a trick of the compiler (that rewrites your code to do it).
If you don't want a closure but you want an additional parameter then you can add an additional parameter to the expression.
You could
Expression<Func<string>> myExpr = () => address;
now you have an expression that closes around your address. Now you only have to combine the two expressions.
You'll have to change the method to:
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 }
);
}
Problem
I want to create lambda something like this ``` user => user.Address == address ``` but is not compiled one, I want to return `LambdaExpression` If the lambda take constant like this ``` user => user.Age == 50 ``` Then I can use this method ``` 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 } ); } ``` How to make this method accept variable `address` come from the scope just outside from the lambda expression? ``` var addressPropertyName = "Address"; var address = new Address() {...}; var q = Repo.GetQuery().Where(PropertyEqual(typeof(User), addressPropertyName, address)) ``` Edit: clarify my question: How build the right `Expression` to generate the first lambda? Update: This is not possible because EF does not support non-scalar variable I change the lambda to `user => user.AddressId == addressId` as suggested here. It just the matter how to get `AddressId` FK `PropertyInfo` from a known navigation property `Address`.