Я искал в Интернете, но все еще не могу найти простой ответ. Может кто-нибудь объяснить (на простом английском), что это GroupJoin
такое? Чем он отличается от обычного внутреннего Join
? Это обычно используется? Это только для синтаксиса метода? Как насчет синтаксиса запроса? Пример кода на C # был бы неплох.
c#
linq
linq-to-entities
duyn9uyen
источник
источник
Ответы:
Поведение
Предположим, у вас есть два списка:
Когда вы
Join
два списка наId
поле, результат будет:Когда вы
GroupJoin
два списка наId
поле, результат будет:Так
Join
выдает плоский (табличный) результат родительских и дочерних значений.GroupJoin
создает список записей в первом списке, каждый из которых содержит группу соединенных записей во втором списке.Вот почему
Join
эквивалентINNER JOIN
в SQL: нет записей дляC
. ХотяGroupJoin
эквивалент эквивалентенOUTER JOIN
:C
находится в наборе результатов, но с пустым списком связанных записей (в наборе результатов SQL будет строкаC - null
).Синтаксис
Так что пусть два списка будут
IEnumerable<Parent>
иIEnumerable<Child>
соответственно. (В случае Linq to Entities:)IQueryable<T>
.Join
синтаксис будетвозвращая
IEnumerable<X>
где X является анонимным типом с двумя свойствами,Value
иChildValue
. Этот синтаксис запроса используетJoin
метод под капотом.GroupJoin
синтаксис будетвозвращая
IEnumerable<Y>
где Y - анонимный тип, состоящий из одного свойства типаParent
и свойства типаIEnumerable<Child>
. Этот синтаксис запроса используетGroupJoin
метод под капотом.Мы могли бы просто сделать
select g
в последнем запросе, который выберетIEnumerable<IEnumerable<Child>>
, скажем, список списков. Во многих случаях выбор с включенным родителем более полезен.Некоторые варианты использования
1. Изготовление плоского внешнего соединения.
Как сказано в заявлении ...
... производит список родителей с дочерними группами. Это можно превратить в плоский список пар родитель-потомок двумя небольшими дополнениями:
Результат похож на
Обратите внимание, что переменная диапазона
c
повторно используется в приведенном выше утверждении. Делая это, любойjoin
оператор может быть просто преобразован в операторouter join
путем добавления эквивалентаinto g from c in g.DefaultIfEmpty()
в существующийjoin
оператор.Это где запрос (или полный) синтаксис сияет. Синтаксис метода (или свободный) показывает, что на самом деле происходит, но трудно написать:
Таким образом, квартира
outer join
в LINQ являетсяGroupJoin
плоскойSelectMany
.2. Сохранение порядка
Предположим, что список родителей немного длиннее. Некоторый пользовательский интерфейс создает список выбранных родителей в виде
Id
значений в фиксированном порядке. Давайте использовать:Теперь выбранные родители должны быть отфильтрованы из списка родителей в этом точном порядке.
Если мы сделаем ...
... порядок
parents
будет определять результат. Если родители заказаныId
, результатом будут родители 2, 3, 4, 7. Не хорошо. Тем не менее, мы также можем использоватьjoin
для фильтрации списка. И используя вids
качестве первого списка, порядок будет сохранен:В результате родители 3, 7, 2, 4.
источник
Согласно eduLINQ :
Единственная разница в заявлении:
Присоединиться :
GroupJoin :
Узнайте больше здесь:
Переопределение LINQ для объектов: часть 19 - объединение
Переопределение LINQ для объектов: часть 22 - GroupJoin
источник