Предполагая, что у меня есть левое внешнее соединение как таковое:
from f in Foo
join b in Bar on f.Foo_Id equals b.Foo_Id into g
from result in g.DefaultIfEmpty()
select new { Foo = f, Bar = result }
Как бы я выразил ту же задачу, используя методы расширения? Например
Foo.GroupJoin(Bar, f => f.Foo_Id, b => b.Foo_Id, (f,b) => ???)
.Select(???)
c#
linq-to-sql
lambda
LaserJesus
источник
источник
GroupJoin
, это левое внешнее соединение,SelectMany
часть нужна только в зависимости от того, что вы хотите выбрать.Так как это, похоже, фактический вопрос SO для левых внешних объединений с использованием синтаксиса метода (расширения), я подумал, что добавлю альтернативу выбранному в настоящее время ответу, который (по моему опыту, по крайней мере) был более распространенным, чем я. после
Чтобы отобразить разницу, используя простой набор данных (при условии, что мы объединяем сами значения):
Вариант 2 соответствует типичному определению левого внешнего соединения, но, как я уже упоминал ранее, часто излишне сложно в зависимости от набора данных.
источник
Single
проверку в процессе объединения.SingleOrDefault
однако это более «правильный» способ продемонстрировать это ИМО.Групповое объединение не является необходимым для объединения двух наборов данных.
Внутреннее соединение:
Для левого соединения просто добавьте DefaultIfEmpty ()
EF и LINQ to SQL правильно преобразуются в SQL. Для LINQ to Objects лучше присоединиться с помощью GroupJoin, так как он внутренне использует Lookup . Но если вы запрашиваете БД, то пропуск GroupJoin считается AFAIK быстрым.
Personlay для меня этот способ более читабелен по сравнению с GroupJoin (). SelectMany ()
источник
Вы можете создать метод расширения, например:
источник
Улучшение ответа Ocelot20: если у вас есть таблица, к которой вы оставляете внешнее соединение, с которой вы просто хотите, чтобы 0 или 1 строка из нее, но она могла иметь несколько, вам нужно упорядочить вашу объединенную таблицу:
В противном случае строка, которую вы получите в объединении, будет случайной (или, более конкретно, в зависимости от того, какой БД будет найден первым).
источник
Превратив ответ Марка Гравелла в метод расширения, я сделал следующее.
источник
Хотя принятый ответ работает и полезен для Linq to Objects, мне не понравилось, что SQL-запрос - это не просто прямое левое внешнее соединение.
Следующий код опирается на проект LinkKit, который позволяет передавать выражения и вызывать их в запросе.
Может использоваться следующим образом
источник
Существует простое решение для этого
Просто используйте .HasValue в вашем выборе
Очень просто, нет необходимости в групповом присоединении или чем-либо еще
источник