Linq Join с динамическим выражением

Я пытаюсь выполнить динамическое соединение в linq. Это означает, что я знаю только во время выполнения, в каком поле произойдет соединение.

Я сделал следующее:

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 });

Однако это выдает во время компиляции, хотя лямбда кажется правильным синтаксисом, говорящим мне, что он не может преобразовать из LambdaExpression в Expression<System.Func<E, int>>.

Как мне заставить его динамически создавать правильное выражение, которое использует мое поле (т.е. свойство «Поле» выше в строке typeof(E).GetMember(Field).First())?


person James Hancock    schedule 15.11.2013    source источник


Ответы (1)


Используйте Expression.Lambda<TDelegate>, чтобы закончить вверх по линии

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

Обновить

Согласно вашему комментарию, причина неудачного выражения заключается в том, что вы используете два разных параметра. Вы определяете itemParam, но затем не используете его в Expression.MakeMemberAccess

Вместо этого попробуйте следующее:

// obj
var itemParam = Expression.Parameter(typeof(E), "obj");

// obj.Field
var entityAccess = Expression.MakeMemberAccess(itemParam, typeof(E).GetMember(Field).First());
person Lukazoid    schedule 15.11.2013
comment
Это компилируется, но затем я получаю: параметр «obj» не был связан в указанном выражении запроса LINQ to Entities. Спасибо! - person James Hancock; 16.11.2013
comment
Взгляните на мое обновление, вам нужно использовать тот же экземпляр, полученный в результате Expression.Parameter - person Lukazoid; 16.11.2013
comment
Нет проблем, я считаю, что запись эквивалента C# в комментарии помогает отслеживать, что происходит. - person Lukazoid; 18.11.2013