Search code examples
c#linqlambdalinq-expressions

Linq Join with Dynamic Expression


I'm attempting to do a dynamic join in linq. Meaning that I only know at runtime what field the join will occur on.

I've done the following:

var itemParam = Expression.Parameter(typeof(E), "obj");
var entityAccess = Expression.MakeMemberAccess(Expression.Parameter(typeof(E), "obj"), typeof(E).GetMember(Field).First());
var lambda = Expression.Lambda(entityAccess, itemParam);
var q = dbSet.Join(context.Acl, lambda, acl => acl.ObjectID, (entity, acl) => new { Entity = entity, ACL = acl });

However this throws at compile time, even though lambda appears to be the right syntax telling me that it cannot convert from LambdaExpression to Expression<System.Func<E, int>>.

How do I get it to create the right expression dynamically that uses my field (i.e. property "Field" above in the typeof(E).GetMember(Field).First()) line?


Solution

  • Use Expression.Lambda<TDelegate>, so that you end up with the line

    // obj => obj.Field
    var lambda = Expression.Lambda<Func<E, int>>(entityAccess, itemParam);
    

    Update

    As per your comment, the reason the expression fails is because you are using two different parameters. You define itemParam, but then do not use it in Expression.MakeMemberAccess

    Try the following instead:

    // obj
    var itemParam = Expression.Parameter(typeof(E), "obj");
    
    // obj.Field
    var entityAccess = Expression.MakeMemberAccess(itemParam, typeof(E).GetMember(Field).First());