Linq to Sql : 여러 개의 왼쪽 외부 조인


160

LINQ to SQL을 사용하여 둘 이상의 왼쪽 외부 조인을 사용하는 방법을 알아내는 데 어려움이 있습니다. 하나의 왼쪽 외부 조인을 사용하는 방법을 이해합니다. VB.NET을 사용하고 있습니다. 아래는 내 SQL 구문입니다.

T-SQL

SELECT
    o.OrderNumber,
    v.VendorName,
    s.StatusName
FROM
    Orders o
LEFT OUTER JOIN Vendors v ON
    v.Id = o.VendorId
LEFT OUTER JOIN Status s ON
    s.Id = o.StatusId
WHERE
    o.OrderNumber >= 100000 AND
    o.OrderNumber <= 200000

답변:


247

이것은 더 깨끗할 수 있습니다 ( 모든 into진술 이 필요하지는 않습니다 ).

var query = 
    from order in dc.Orders
    from vendor 
    in dc.Vendors
        .Where(v => v.Id == order.VendorId)
        .DefaultIfEmpty()
    from status 
    in dc.Status
        .Where(s => s.Id == order.StatusId)
        .DefaultIfEmpty()
    select new { Order = order, Vendor = vendor, Status = status } 
    //Vendor and Status properties will be null if the left join is null

또 다른 왼쪽 조인 예제가 있습니다.

var results = 
    from expense in expenseDataContext.ExpenseDtos
    where expense.Id == expenseId //some expense id that was passed in
    from category 
    // left join on categories table if exists
    in expenseDataContext.CategoryDtos
                         .Where(c => c.Id == expense.CategoryId)
                         .DefaultIfEmpty() 
    // left join on expense type table if exists
    from expenseType 
    in expenseDataContext.ExpenseTypeDtos
                         .Where(e => e.Id == expense.ExpenseTypeId)
                         .DefaultIfEmpty()
    // left join on currency table if exists
    from currency 
    in expenseDataContext.CurrencyDtos
                         .Where(c => c.CurrencyID == expense.FKCurrencyID)
                         .DefaultIfEmpty() 
    select new 
    { 
        Expense = expense,
        // category will be null if join doesn't exist
        Category = category,
        // expensetype will be null if join doesn't exist
        ExpenseType = expenseType,
        // currency will be null if join doesn't exist
        Currency = currency  
    }

12
@manitra : 아니요, 실제로 LEFT OUTER JOIN 문을 얻습니다 (중첩 된 선택 없음). 꽤 미친 허?
Amir

6
모든 into 문을 사용하는 것보다이 방법이 더 좋습니다. 이것을 게시 해 주셔서 감사합니다!
Bryan Roth

7
이것은 모든 종류의 달콤한입니다. 그러나 : wtf 왜 조인이 있으면 linq에 왼쪽 조인이 없습니까? 내부 조인 만하는 세트 기반 세계는 무엇입니까? Grrr.
jcollum

2
이것은 단지 내 얼굴에 큰 웃음을 주었다. 따라하기 쉬운 예제에 감사드립니다.
nycdan

2
나는 이것을 시도했고 @tvanfosson의 방법보다 훨씬 느리다. 데이터베이스에 대해 직접 수행하지 않고 객체에 대한 linq에서 엄격하게 수행했습니다. 나는 500000 비용, 4000 categoryDtos 및 4000 costTypeDtos에 해당합니다. 달리는 데 1 분이 걸렸습니다. tvanfosson의 구문을 사용하면 6 초가 걸립니다.
Chris

49

VisualStudio에 액세스 할 수는 없지만 (저는 Mac에 있습니다) http://bhaidar.net/cs/archive/2007/08/01/left-outer-join-in-linq-to 의 정보를 사용하십시오. -sql.aspx 다음과 같이 할 수 있습니다.

var query = from o in dc.Orders
            join v in dc.Vendors on o.VendorId equals v.Id into ov
            from x in ov.DefaultIfEmpty()
            join s in dc.Status on o.StatusId equals s.Id into os
            from y in os.DefaultIfEmpty()
            select new { o.OrderNumber, x.VendorName, y.StatusName }

22

LINQ to SQL을 사용하여 VB.NET에서 여러 개의 왼쪽 외부 조인을 사용하는 방법을 알아 냈습니다.

Dim db As New ContractDataContext()

Dim query = From o In db.Orders _
            Group Join v In db.Vendors _
            On v.VendorNumber Equals o.VendorNumber _
            Into ov = Group _
            From x In ov.DefaultIfEmpty() _
            Group Join s In db.Status _
            On s.Id Equals o.StatusId Into os = Group _
            From y In os.DefaultIfEmpty() _
            Where o.OrderNumber >= 100000 And o.OrderNumber <= 200000 _
            Select Vendor_Name = x.Name, _
                   Order_Number = o.OrderNumber, _
                   Status_Name = y.StatusName

8

기능을 사용하는 VB.NET에서

Dim query = From order In dc.Orders
            From vendor In 
            dc.Vendors.Where(Function(v) v.Id = order.VendorId).DefaultIfEmpty()
            From status In 
            dc.Status.Where(Function(s) s.Id = order.StatusId).DefaultIfEmpty()
            Select Order = order, Vendor = vendor, Status = status 

3

게시물에 사용 된 방법을 따라야한다고 생각합니다 . 정말 추악 해 보이지만 두 번 할 수 있고 원하는 결과를 얻을 수 있다고 생각합니다.

이것이 실제로 DataContext.ExecuteCommand(...)linq로 변환 하는 대신 사용 하는 것이 더 나은 경우인지 궁금합니다 .


0

내 linq 쿼리를 응용 프로그램에 사용하고 있습니다. 이것이 귀하의 요구 사항과 일치하면 이것을 참조 할 수 있습니다. 여기에 3 개의 테이블이있는 왼쪽 외부 조인이 있습니다.

 Dim result = (From csL In contractEntity.CSLogin.Where(Function(cs) cs.Login = login AndAlso cs.Password = password).DefaultIfEmpty
                   From usrT In contractEntity.UserType.Where(Function(uTyp) uTyp.UserTypeID = csL.UserTyp).DefaultIfEmpty ' <== makes join left join
                   From kunD In contractEntity.EmployeeMaster.Where(Function(kunDat) kunDat.CSLoginID = csL.CSLoginID).DefaultIfEmpty
                   Select New With {
                  .CSLoginID = csL.CSLoginID,
                  .UserType = csL.UserTyp}).ToList()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.