Это общая форма (как уже было сказано в других ответах)
var c =
from a in alpha
join b in beta on b.field1 equals a.field1 into b_temp
from b_value in b_temp.DefaultIfEmpty()
select new { Alpha = a, Beta = b_value };
Однако вот объяснение, которое, я надеюсь, прояснит, что это на самом деле означает!
join b in beta on b.field1 equals a.field1 into b_temp
по существу создает отдельный набор результатов b_temp, который эффективно включает в себя нулевые «строки» для записей в правой части (записи в «b»).
Затем следующая строка:
from b_value in b_temp.DefaultIfEmpty()
.. итерации по этому набору результатов, установив значение по умолчанию для «строки» справа, и установив результат строки правой стороны, присоединитесь к значению «b_value» (то есть значение, которое находится на правая сторона, если есть соответствующая запись, или «null», если нет).
Теперь, если правая сторона является результатом отдельного запроса LINQ, она будет состоять из анонимных типов , который может быть только «чем-то» или «нулевым». Однако, если это перечислимо (например, List - где MyObjectB - это класс с 2 полями), тогда можно указать, какие значения по умолчанию для него используются «null»:
var c =
from a in alpha
join b in beta on b.field1 equals a.field1 into b_temp
from b_value in b_temp.DefaultIfEmpty( new MyObjectB { Field1 = String.Empty, Field2 = (DateTime?) null })
select new { Alpha = a, Beta_field1 = b_value.Field1, Beta_field2 = b_value.Field2 };
гарантирует, что «b» сам по себе не является нулевым (но его свойства могут быть пустыми, используя заданные по умолчанию значения null, которые вы указали), и это позволяет вам проверять свойства b_value, не получая исключение нулевой ссылки для b_value. Обратите внимание, что для нулевой даты DateTime тип (DateTime?), То есть «nullable DateTime», должен быть указан как «Тип» нулевого значения в спецификации для «DefaultIfEmpty» (это также относится к типам, которые не являются «изначально» 'nullable, например double, float.
Вы можете выполнить несколько левых внешних соединений, просто связав вышеупомянутый синтаксис.
Мне удалось решить проблему. Оказывается, карты вращаются назад. После правильного поворота они отлично работали.