LINQ to SQL Left Outer Join

Этот запрос эквивалентен соединению LEFT OUTER?

//assuming that I have a parameter named 'invoiceId' of type int
from c in SupportCases
let invoice = c.Invoices.FirstOrDefault(i=> i.Id == invoiceId)
where (invoiceId == 0 || invoice != null)    
select new 
{
      Id = c.Id
      , InvoiceId = invoice == null ? 0 : invoice.Id
}
4b9b3361

Не совсем - поскольку каждая "левая" строка в левом-внешнем соединении будет соответствовать 0-n "правым" строкам (во второй таблице), где - так как ваш соответствует только 0-1. Чтобы сделать левое внешнее соединение, вам нужны SelectMany и DefaultIfEmpty, например:

var query = from c in db.Customers
            join o in db.Orders
               on c.CustomerID equals o.CustomerID into sr
            from x in sr.DefaultIfEmpty()
            select new {
               CustomerID= c.CustomerID, ContactName=c.ContactName,
               OrderID = x.OrderID == null ? -1 : x.OrderID};   

(или с помощью методов расширения)

140
ответ дан 31 марта '09 в 11:33
источник

Вам не нужны инструкции:

var query = 
    from customer in dc.Customers
    from order in dc.Orders
         .Where(o => customer.CustomerId == o.CustomerId)
         .DefaultIfEmpty()
    select new { Customer = customer, Order = order } 
    //Order will be null if the left join is null

И да, запрос выше действительно создает объединение LEFT OUTER.

Ссылка на аналогичный вопрос, который обрабатывает несколько левых объединений: Linq to Sql: несколько левых внешних соединений

175
ответ дан 19 янв. '11 в 22:32
источник

Я нашел 1 решение. если вы хотите перевести этот тип SQL (левое объединение) в Linq Entity...

SQL:

SELECT * FROM [JOBBOOKING] AS [t0]
LEFT OUTER JOIN [REFTABLE] AS [t1] ON ([t0].[trxtype] = [t1].[code])
                                  AND ([t1]. [reftype] = "TRX")

LINQ:

from job in JOBBOOKINGs
join r in (from r1 in REFTABLEs where r1.Reftype=="TRX" select r1) 
          on job.Trxtype equals r.Code into join1
from j in join1.DefaultIfEmpty()
select new
{
   //cols...
}
4
ответ дан 23 дек. '10 в 5:51
источник

Я хотел бы добавить еще одну вещь. В LINQ to SQL, если ваша БД правильно построена, а ваши таблицы связаны с ограничениями внешнего ключа, то вам вообще не нужно делать соединение.

Используя LINQPad, я создал следующий запрос LINQ:

//Querying from both the CustomerInfo table and OrderInfo table
from cust in CustomerInfo
where cust.CustomerID == 123456
select new {cust, cust.OrderInfo}

Что было переведено в (слегка усеченный) запрос ниже

 -- Region Parameters
 DECLARE @p0 Int = 123456
-- EndRegion
SELECT [t0].[CustomerID], [t0].[AlternateCustomerID],  [t1].[OrderID], [t1].[OnlineOrderID], (
    SELECT COUNT(*)
    FROM [OrderInfo] AS [t2]
    WHERE [t2].[CustomerID] = [t0].[CustomerID]
    ) AS [value]
FROM [CustomerInfo] AS [t0]
LEFT OUTER JOIN [OrderInfo] AS [t1] ON [t1].[CustomerID] = [t0].[CustomerID]
WHERE [t0].[CustomerID] = @p0
ORDER BY [t0].[CustomerID], [t1].[OrderID]

Обратите внимание на LEFT OUTER JOIN выше.

1
ответ дан 03 апр. '15 в 16:21
источник