Если вы сделаете поле secondSalesPersonId
в таблице базы данных обнуляемым, LINQ-to-SQL должен правильно построить объект Association, чтобы результирующий оператор SQL выполнил LEFT OUTER JOIN
.
UPDATE:
Поскольку поле может быть пустым, ваша проблема может быть в явном объявлении dataLoadOptions.LoadWith<>()
. У меня похожая ситуация в моем текущем проекте, где у меня есть Заказ, но заказ проходит несколько этапов. Каждый этап соответствует отдельной таблице с данными, относящимися к этому этапу. Я просто получаю Заказ, и соответствующие данные следуют, если он существует. Я вообще не использую dataLoadOptions
, и он делает то, что мне нужно. Например, если в Заказе есть запись заказа на покупку, но нет записи счета-фактуры, Order.PurchaseOrder
будет содержать данные заказа на покупку, а Order.Invoice
будет нулевым. Мой запрос выглядит примерно так:
DC.Orders.Where(a => a.Order_ID == id).SingleOrDefault();
Я стараюсь не управлять LINQ-to-SQL на микроуровне ... он делает 95% того, что мне нужно, прямо из коробки.
ОБНОВЛЕНИЕ 2:
Я нашел этот пост , в котором обсуждается использование DefaultIfEmpty () для заполнения дочерних сущностей нулем, если они не существуют. Я опробовал его с помощью LINQPad в своей базе данных и преобразовал этот пример в лямбда-синтаксис (поскольку я это и использую):
ParentTable.GroupJoin
(
ChildTable,
p => p.ParentTable_ID,
c => c.ChildTable_ID,
(p, aggregate) => new { p = p, aggregate = aggregate }
)
.SelectMany (a => a.aggregate.DefaultIfEmpty (),
(a, c) => new
{
ParentTableEntity = a.p,
ChildTableEntity = c
}
)
Из того, что я могу понять из этого оператора, выражение GroupJoin связывает родительскую и дочернюю таблицы, а выражение SelectMany объединяет связанные дочерние записи. Похоже, что ключом является использование DefaultIfEmpty, которое принудительно включает запись родительской сущности, даже если нет связанных дочерних записей. (Спасибо, что заставили меня углубиться в это ... Я думаю, я мог бы найти кое-что полезное, чтобы помочь с довольно большим отчетом, который я получил на своем конвейере ...)
ОБНОВЛЕНИЕ 3:
Если цель состоит в том, чтобы сделать его простым, то похоже, что вам придется ссылаться на эти поля продавца непосредственно в выражении Select (). Причина, по которой вам в первую очередь нужно использовать LoadWith <> (), заключается в том, что на таблицы нет ссылок нигде в вашем запросе, поэтому механизм LINQ не будет автоматически извлекать эту информацию.
В качестве примера приведена такая структура:
MailingList ListCompany
=========== ===========
List_ID (PK) ListCompany_ID (PK)
ListCompany_ID (FK) FullName (string)
Я хочу получить название компании, связанной с определенным списком рассылки:
MailingLists.Where(a => a.List_ID == 2).Select(a => a.ListCompany.FullName)
Если эта связь НЕ была создана, то есть поле ListCompany_ID
в таблице MailingList
для этой записи равно null
, это результирующий SQL, сгенерированный механизмом LINQ:
SELECT [t1].[FullName]
FROM [MailingLists] AS [t0]
LEFT OUTER JOIN [ListCompanies] AS [t1] ON [t1].[ListCompany_ID] = [t0].[ListCompany_ID]
WHERE [t0].[List_ID] = @p0