LINQ: левое внешнее соединение с несколькими условиями - PullRequest
1 голос
/ 29 ноября 2011

У меня есть два IEnumerable с именами BaseReportDefinitions и InputReportDefinitions.Мне нужно сделать левое внешнее соединение, где я хочу, чтобы все InputReportDefinitions и в зависимости от того BaseReportDefinitions, которые совпадают.Оба IEnumberables содержат объекты ReportDefinition, которые содержат свойства ParentName и ReportName, которые необходимо использовать в качестве ключа соединения.Я хочу вернуть объект ReportDefinition для каждого (в случае записи BaseReportDefinition он может быть нулевым) в анонимном объекте.

Я видел много примеров внешних объединений linq и внешних объединений со статическим вторым условием, которое часто помещается в условие where, но ничего, что действительно не использует два условия полностью для объединения.

1 Ответ

8 голосов
/ 29 ноября 2011
var items = inputReportDefinitions.GroupJoin(
              baseReportDefinitions,
              firstSelector => new {
                         firstSelector.ParentName, firstSelector.ReportName
                                   },
              secondSelector => new {
                         secondSelector.ParentName, secondSelector.ReportName
                                   },
              (inputReport, baseCollection) => new {inputReport, baseCollection})
              .SelectMany(grp => grp.baseCollection.DefaultIfEmpty(),
                         (col, baseReport) => new
                                                 {
                                                    Base = baseReport,
                                                    Input = col.inputReport
                                                 });

Я считаю, что это в конечном итоге является левым внешним соединением Я не знаю, как преобразовать это чудовище в оператор запроса. Я думаю, что если вы добавите AsQueryable() до конца, его можно будет использовать в Linq-to-SQL, но, честно говоря, у меня мало опыта с этим.

РЕДАКТИРОВАТЬ: Я понял это. Гораздо проще читать:

var otherItems = from i in inputReportDefinitions
                         join b in baseReportDefinitions
                         on new {i.ParentName, i.ReportName} 
                         equals new {b.ParentName, b.ReportName} into other
                         from baseReport in other.DefaultIfEmpty()
                         select new
                                    {
                                        Input = i,
                                        Base = baseReport
                                    };
...