Как выполнить левое внешнее соединение в C # LINQ для объектов без использования join-on-equals-into
предложений? Есть ли способ сделать это сwhere
пункта? Правильная проблема: для внутреннего объединения легко, и у меня есть решение как это
List<JoinPair> innerFinal = (from l in lefts from r in rights where l.Key == r.Key
select new JoinPair { LeftId = l.Id, RightId = r.Id})
но для левого внешнего соединения мне нужно решение. Мой что-то вроде этого, но он не работает
List< JoinPair> leftFinal = (from l in lefts from r in rights
select new JoinPair {
LeftId = l.Id,
RightId = ((l.Key==r.Key) ? r.Id : 0
})
где JoinPair является классом:
public class JoinPair { long leftId; long rightId; }
Ответы:
Как указано на:
101 LINQ Samples - Левое внешнее соединение
источник
Если используется поставщик LINQ, управляемый базой данных, значительно более читаемое левое внешнее объединение можно записать так:
Если вы пропустите, у
DefaultIfEmpty()
вас будет внутреннее соединение.Возьми принятый ответ:
Этот синтаксис очень сбивает с толку, и неясно, как он работает, когда вы хотите оставить объединенные таблицы MULTIPLE.
Примечание
Следует отметить, что
from alias in Repo.whatever.Where(condition).DefaultIfEmpty()
это то же самое, что и external-apply / left-join-lateral, которую любой (приличный) оптимизатор базы данных вполне может преобразовать в левое объединение, если вы не вводите для каждой строки -значения (то есть фактическое внешнее применение). Не делайте этого в Linq-2-Objects (потому что нет никакого DB-оптимизатора, когда вы используете Linq-to-Objects).Подробный пример
При использовании с LINQ 2 SQL он будет хорошо переведен в следующий очень разборчивый SQL-запрос:
Редактировать:
См. Также « Преобразование запроса SQL Server в запрос Linq » для более сложного примера.
Кроме того, если вы делаете это в Linq-2-Objects (вместо Linq-2-SQL), вы должны сделать это старомодным способом (потому что LINQ to SQL переводит это правильно, чтобы объединить операции, но поверх объектов этот метод вызывает полное сканирование и не использует поиск по индексу, вообще ...):
источник
join
намного более читабелен и понятен, чемwhere
сопровождаемыйDefaultIfEmpty
Использование лямбда-выражения
источник
Enumerable.Empty<Product>.DefaultIfEmpty()
будет возвращать IEnumerable с одним значениемdefault(Product)
.Теперь в качестве метода расширения:
Используйте, как вы обычно используете join:
Надеюсь, это сэкономит вам время.
источник
Посмотрите на этот пример . Этот запрос должен работать:
источник
r
быть доступны в выбранном пункте после использования объединения в?r
во второмfrom
пункте. т.е. вfrom r in lrs.DefaultIfEmpty()
противном случае этот запрос не имеет особого смысла и, вероятно, даже не компилируется из-r
за неконтролируемого выбора.Clockwise
с Джоном Клизом, смеется.Реализация левого внешнего соединения методами расширения может выглядеть так
Затем селектор результатов должен позаботиться о пустых элементах. Fx.
источник
взгляните на этот пример
Теперь вы можете,
include elements from the left
даже если этот элементhas no matches in the right
, в нашем случае мы восстановили,Arlene
даже если он не имеет соответствия в правомвот ссылка
Как выполнить левое внешнее соединение (Руководство по программированию в C #)
источник
Это общая форма (как уже указано в других ответах)
Однако вот объяснение, которое, я надеюсь, прояснит, что это на самом деле означает!
по существу создает отдельный результирующий набор b_temp, который фактически содержит нулевые «строки» для записей справа (записи в «b»).
Тогда следующая строка:
..iterate над этим результирующим набором, устанавливая нулевое значение по умолчанию для 'строки' с правой стороны, и устанавливая результат соединения строки правой стороны со значением 'b_value' (то есть значением, которое находится справа стороны, если есть совпадающая запись, или 'null', если ее нет).
Теперь, если правая часть является результатом отдельного запроса LINQ, он будет состоять из анонимных типов, которые могут быть либо «чем-то», либо «нулем». Однако, если он перечислим (например, List - где MyObjectB - это класс с 2 полями), тогда можно быть конкретным относительно того, какие значения по умолчанию «null» используются для его свойств:
Это гарантирует, что само «b» не является нулевым (но его свойства могут быть нулевыми, используя заданные вами значения по умолчанию), и это позволяет вам проверять свойства b_value без получения исключения нулевой ссылки для b_value. Обратите внимание, что для обнуляемого DateTime тип (DateTime?), То есть «обнуляемый DateTime» должен быть указан как «Тип» нулевого значения в спецификации для «DefaultIfEmpty» (это также будет применяться к типам, которые не являются «изначально»). обнуляемый, например, double, float).
Вы можете выполнить несколько левых внешних объединений, просто связав приведенный выше синтаксис.
источник
Вот пример, если вам нужно объединить более двух таблиц:
Ссылка: https://stackoverflow.com/a/17142392/2343
источник
Метод расширения, который работает как левое соединение с синтаксисом соединения
только что написал это в ядре .NET, и, кажется, работает как положено.
Небольшой тест:
источник
Вот довольно простая для понимания версия с использованием синтаксиса метода:
источник
Существует три таблицы: people, школы и people_schools, которые связывают людей со школами, в которых они учатся. Ссылка на человека с id = 6 отсутствует в таблице people_schools. Однако человек с id = 6 представлен в итоговой таблице.
источник
Это синтаксис SQL по сравнению с синтаксисом LINQ для внутренних и левых внешних объединений. Левое внешнее соединение:
http://www.ozkary.com/2011/07/linq-to-entity-inner-and-left-joins.html
«В следующем примере выполняется групповое объединение между продуктом и категорией. По сути, это левое соединение. Выражение into возвращает данные, даже если таблица категорий пуста. Чтобы получить доступ к свойствам таблицы категорий, мы должны теперь выбрать из перечисляемого результата добавив from cl в оператор catList.DefaultIfEmpty ().
источник
Выполнить левые внешние объединения в linq C # // Выполнить левые внешние объединения
https://dotnetwithhamid.blogspot.in/
источник
Я хотел бы добавить, что если вы получите расширение MoreLinq, теперь есть поддержка как гомогенных, так и гетерогенных левых соединений.
http://morelinq.github.io/2.8/ref/api/html/Overload_MoreLinq_MoreEnumerable_LeftJoin.htm
пример:
РЕДАКТИРОВАТЬ:
Оглядываясь назад, это может сработать, но оно преобразует IQueryable в IEnumerable, так как morelinq не преобразует запрос в SQL.
Вместо этого вы можете использовать GroupJoin, как описано здесь: https://stackoverflow.com/a/24273804/4251433
Это гарантирует, что он останется IQueryable на случай, если вам потребуется выполнить дальнейшие логические операции над ним позже.
источник
Простой способ - использовать ключевое слово Let. Это работает для меня.
Это симуляция левого соединения. Если каждый элемент в таблице B не соответствует элементу A, BItem возвращает ноль
источник
Если вам нужно присоединиться и отфильтровать что-то, это можно сделать за пределами объединения. Фильтр можно сделать после создания коллекции.
В этом случае, если я сделаю это в условии соединения, я уменьшу количество возвращаемых строк.
Тройное состояние используется
(= n == null ? "__" : n.MonDayNote,)
Если объект
null
(так что нет совпадения), то вернуть то, что после?
.__
, в этом случае.В противном случае, вернуть то , что после того
:
,n.MonDayNote
.Спасибо другим авторам, с которых я начал свою собственную проблему.
источник
ВЫВОД
источник
Согласно моему ответу на подобный вопрос, здесь:
Linq to SQL оставил внешнее объединение с использованием синтаксиса Lambda и объединение в 2 столбца (составной ключ объединения)
Получить код здесь или клонировать мой репозиторий Github , и играть!
Запрос:
Lambda:
источник
Обзор: в этом фрагменте кода я демонстрирую, как группировать по идентификатору, где у таблиц 1 и 2 есть отношения один ко многим. Я группируюсь по Id, Field1 и Field2. Подзапрос полезен, если требуется третий просмотр таблицы, и для этого потребовалось бы левое соединение. Я показываю левую группу соединений и подзапрос linq. Результаты эквивалентны.
источник
источник
Простое решение для LEFT OUTER JOIN :
примечания :
источник
setA
иsetB
ответ.