2008-11-06 6 views
150

j'ai du mal à comprendre comment utiliser plus d'une jointure externe gauche en utilisant LINQ to SQL. Je comprends comment utiliser une jointure externe gauche. J'utilise VB.NET. Voici ma syntaxe SQL.LINQ to SQL: externe gauche plusieurs jointures

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 

Répondre

233

Cela peut être plus propre (vous ne besoin de toutes les déclarations 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 

Voici une autre jointure gauche exemple

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 
    } 
+1

A quoi ressemble le SQL généré? Ne contient-il pas cette sélection imbriquée? –

+11

@manitra: Non, vous obtenez des instructions LEFT OUTER JOIN (pas de sélection imbriquée). Assez fou hein? – Amir

+0

Bonne nouvelle parce que, cette syntaxe est assez claire :) –

2

Je pense que vous devriez être en mesure de suivre la méthode utilisée dans this après. Il a l'air vraiment moche, mais je pense que vous pourriez le faire deux fois et obtenir le résultat que vous voulez.

Je me demande si cela est en fait un cas où vous seriez mieux à l'aide DataContext.ExecuteCommand(...) au lieu de convertir à LINQ.

45

Ne pas avoir accès à VisualStudio (je suis sur mon Mac), mais en utilisant les informations de http://bhaidar.net/cs/archive/2007/08/01/left-outer-join-in-linq-to-sql.aspx il semble que vous pourriez être en mesure de faire quelque chose comme ceci:

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 } 
21

je me suis dit comment utiliser externe multiple gauche se joint à VB.NET en utilisant LINQ to SQL:

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 
7

En VB.NET en utilisant la fonction,

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 
0

J'utilise cette requête LINQ pour mon application. Si cela correspond à votre exigence, vous pouvez vous y référer. ici j'ai rejoint (Left outer join) avec 3 tables.

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()