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?
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());