2008-11-06 13 views
150

Tengo algunos problemas para descubrir cómo usar más de una combinación externa izquierda utilizando LINQ to SQL. Entiendo cómo usar una combinación externa izquierda. Estoy usando VB.NET. A continuación está mi sintaxis SQL.Linq a Sql: varias combinaciones externas a la izquierda

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 

Respuesta

233

Esto puede ser más limpio (usted no necesita todas las declaraciones 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 

Aquí hay otra izquierda se unen ejemplo

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

¿Cómo se ve el SQL generado? ¿No contiene anidado seleccionar de esta manera? –

+11

@manitra: No, en realidad obtienes las declaraciones LEFT OUTER JOIN (sin selecciones anidadas). Bastante loco ¿eh? – Amir

+0

Buenas noticias porque, esta sintaxis es bastante clara :) –

2

creo que debería ser capaz de seguir el método utilizado en this puesto. Se ve muy feo, pero creo que podrías hacerlo dos veces y obtener el resultado que deseas.

Me pregunto si este es realmente un caso en el que sería mejor usar DataContext.ExecuteCommand(...) en lugar de convertir a linq.

45

no tienen acceso a VisualStudio (estoy en mi Mac), pero utilizando la información de http://bhaidar.net/cs/archive/2007/08/01/left-outer-join-in-linq-to-sql.aspx Parece que puede ser capaz de hacer algo como esto:

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

me di cuenta de cómo utilizar múltiples externa izquierda se une en VB.NET utilizando LINQ a 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 utilizando la función,

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

estoy usando esta consulta LINQ para mi aplicación. Si esto coincide con su requisito, puede referir esto. aquí me he unido (combinación externa izquierda) con 3 tablas.

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