Я пытающегося сделать внешнее соединение по двум наборам данных, используя следующее выражение:Преобразование заявление GroupJoin к Expression Tree
var destinationList = inners.GroupJoin(outers, inner => inner.JoinField, outer => outer.JoinField,
(inner, outerList) =>
outerList.Select(outer => new DestinationModel { Id = inner.JoinField, AggregationField = outer.DataField })
.DefaultIfEmpty(new DestinationModel { Id = inner.JoinField })).SelectMany(destination => destination).ToList();
Это работает правильно без проблем, но я в конечном счете нужно преобразовать это дерева выражений, позволяющего изменять наборы данных и поля.
Мои модели данных выглядит следующим образом:
InnerModel: общественный класс InnerModel { общественного ИНТ JoinField; public decimal DataField; }
OuterModel: общественный класс OuterModel { общественного ИНТ JoinField; public decimal DataField; }
DestinationModel: общественный класс DestinationModel { общественного ИНТ Id; public decimal AggregationField; }
Внутренние составляющие является List<InnerModel>
Outers является List<OuterModel>
мне удалось получить большую часть пути, но я падаю короткий на последнем шаге. Это то, что у меня есть до сих пор:
// Declare variables
var innerParameter = Expression.Parameter(typeof (InnerModel), "inner");
var innerSelect = Expression.Lambda<Func<InnerModel, int>>(Expression.Field(innerParameter, "JoinField"), innerParameter);
var outerParameter = Expression.Parameter(typeof (OuterModel), "outer");
var outerListParameter = Expression.Parameter(typeof (IEnumerable<OuterModel>), "outerList");
var outerSelect = Expression.Lambda<Func<OuterModel, int>>(Expression.Field(outerParameter, "JoinField"), outerParameter);
var existingBinding = Expression.MemberInit(Expression.New(typeof (DestinationModel)), Expression.Bind(typeof (DestinationModel).GetField("Id"), Expression.Field(innerParameter, "JoinField")));
// Create lambdas
var selector = Expression.Lambda<Func<OuterModel, DestinationModel>>(existingBinding, outerParameter);
var selectMethod = typeof (Enumerable).GetMethods().First(x => x.Name == "Select" && x.GetParameters().Length == 2).MakeGenericMethod(typeof(OuterModel), typeof(DestinationModel));
var selectCall = Expression.Call(selectMethod, outerListParameter, selector);
// Create the inner key selector for the GroupJoin method
var innerKeySelector = Expression.Lambda(selectCall, innerParameter, outerListParameter);
Все работает до этого момента. Когда я пытаюсь подключить innerKeySelector в первоначальное заявление:
var result = inners.GroupJoin(outers, innerSelect.Compile(), outerSelect.Compile(), (inner, outerList) => outerList.Select(outer => new DestinationModel {Id = inner.JoinField, AggregationField = outer.DataField}).DefaultIfEmpty(new DestinationModel {Id = inner.JoinField})).SelectMany(destination => destination).ToList();
я получаю ошибку компиляции:
аргументы типа для метода «Enumerable.GroupJoin (IEnumerable, IEnumerable, Func, Func, Func, TResult >) 'не может быть выведено из использования. Попробуйте явно указать аргументы типа.
Я знаю, что мне просто не хватает чего-то очевидного, но после работы над этим в течение нескольких часов я не вижу его. Может ли кто-нибудь указать мне в правильном направлении?
За исключением того, что пришлось переименовывать классы моделей в 'xxxTestModel', я не получаю никакой компиляции с опубликованным кодом. –
Я исправил имена классов в коде и упростил некоторые вызовы, но до сих пор получаю ошибку. – MichaelDotKnox