Da Linq a Sql: più join esterni a sinistra

Sto avendo qualche problema a capire come usare più di un join esterno sinistro usando LINQ to SQL. Capisco come usare un join esterno sinistro. Sto usando VB.NET. Di seguito è la mia syntax 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 

Questo potrebbe essere più pulito ( non hai bisogno di tutte le istruzioni ):

 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 

Ecco un altro esempio di join sinistro

 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 } 

Non ho accesso a VisualStudio (sono sul mio Mac), ma usando le informazioni da http://bhaidar.net/cs/archive/2007/08/01/left-outer-join-in-linq-to -sql.aspx sembra che tu possa essere in grado di fare qualcosa del genere:

 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 } 

Ho scoperto come utilizzare più join esterni a sinistra in VB.NET usando 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 

In VB.NET usando la funzione,

 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 

Penso che dovresti essere in grado di seguire il metodo usato in questo post. Sembra davvero brutto, ma penserei che potresti farlo due volte e ottenere il risultato desiderato.

Mi chiedo se questo è effettivamente un caso in cui sarebbe meglio utilizzare DataContext.ExecuteCommand(...) invece di convertire in linq.

Sto usando questa query linq per la mia applicazione. se questo corrisponde al tuo requisito puoi segnalarlo. qui ho unito (Left outer join) con 3 tavoli.

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