이 쿼리는 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
}
답변
왼쪽-외부 조인의 각 “왼쪽”행은 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 == 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
그리고 예, 위의 쿼리는 실제로 LEFT OUTER 조인을 만듭니다.
여러 왼쪽 조인을 처리하는 비슷한 질문에 연결 :
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
답변
1 솔루션을 찾았습니다. 이런 종류의 SQL (왼쪽 조인)을 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에서 DB가 올바르게 빌드되고 테이블이 외래 키 제약 조건을 통해 관련된 경우에는 조인을 전혀 수행 할 필요가 없습니다.
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
위를 주목하십시오 .
답변
성능을 관리하십시오.
적어도 EF Core 에서는 여기에 주어진 다른 답변이 다른 성능을 초래할 수 있다는 것을 경험했습니다 . OP가 Linq to SQL에 대해 물었다는 것을 알고 있지만 EF Core에서도 동일한 질문이 발생하는 것으로 보입니다.
내가 처리해야 할 특정 사례에서 Marc Gravell의 (구문 적으로 더 좋은) 제안은 Mike U가 묘사 한 것과 유사하게 크로스 적용 내부에서 왼쪽 조인을 초래 하여이 특정 쿼리의 추정 비용이 2라는 결과를 얻었습니다. 교차 조인이없는 쿼리에 비해 시간이 많이 걸립니다 . 서버 실행 시간 은 3 배로 다릅니다 . [1]
Marc Gravell의 솔루션으로 교차 조인이없는 쿼리가 발생했습니다.
컨텍스트 : 기본적으로 두 테이블에서 두 개의 왼쪽 조인을 수행해야했는데 각각의 테이블에는 다시 다른 테이블에 대한 조인이 필요했습니다. 또한 왼쪽 조인을 적용 해야하는 테이블에 다른 위치 조건을 지정해야했습니다. 또한 기본 테이블에 두 개의 내부 조인이있었습니다.
예상 운영자 비용 :
- 크로스 적용 : 0.2534
- 십자가없이 적용 : 0.0991.
서버 실행 시간 (ms) (쿼리가 10 번 실행되었으며 SET STATISTICS TIME ON을 사용하여 측정 된 쿼리) :
- 크로스 적용 : 5, 6, 6, 6, 6, 6, 6, 6, 6, 6
- 크로스 적용없이 : 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
(처음 실행은 두 쿼리 모두에 대해 느려졌습니다. 캐시 된 것으로 보입니다.)
테이블 크기 :
- 메인 테이블 : 87 행,
- 왼쪽 조인의 첫 번째 테이블 : 179 행;
- 왼쪽 조인의 두 번째 테이블 : 7 행
EF 코어 버전 : 2.2.1.
SQL Server 버전 : MS SQL Server 2017-14 … (Windows 10).
모든 관련 테이블에는 기본 키에 대한 인덱스 만있었습니다.
내 결론 : 생성 된 SQL은 실제로 다를 수 있으므로 항상 보는 것이 좋습니다.
[1] 흥미롭게도 MS SQL Server Management Studio에서 ‘클라이언트 통계’를 설정할 때 반대 경향을 볼 수있었습니다. 즉, 교차 적용이없는 마지막 솔루션 실행에는 1 초 이상이 걸렸습니다. 내 설정에 문제가 있다고 생각합니다.