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`.

Original source

Related problems