LINQ to SQL левое внешнее соединение
этот запрос эквивалентен a 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
}
5 ответов:
не совсем - так как каждая "левая" строка в левом внешнем соединении будет соответствовать 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};
вам не нужны операторы into:
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
и да, запрос выше действительно создает левое внешнее соединение.
ссылка на аналогичный вопрос, который обрабатывает несколько левых соединений: Linq to Sql: несколько левых внешних соединений
Public Sub LinqToSqlJoin07() Dim q = From e In db.Employees _ Group Join o In db.Orders On e Equals o.Employee Into ords = Group _ From o In ords.DefaultIfEmpty _ Select New With {e.FirstName, e.LastName, .Order = o} ObjectDumper.Write(q) End Sub
проверить http://msdn.microsoft.com/en-us/vbasic/bb737929.aspx
Я нашел 1 решение. если вы хотите перевести этот тип SQL (left join) в объект Linq...
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... }
Я хотел бы добавить еще одну вещь. В 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
выше.