Vb.net Linq到Sql:多个左外部联接

Vb.net Linq到Sql:多个左外部联接,vb.net,linq,linq-to-sql,tsql,left-join,Vb.net,Linq,Linq To Sql,Tsql,Left Join,我在弄清楚如何使用LINQtoSQL使用多个左外部联接时遇到了一些问题。我知道如何使用一个左外连接。我正在使用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.

我在弄清楚如何使用LINQtoSQL使用多个左外部联接时遇到了一些问题。我知道如何使用一个左外连接。我正在使用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
选择
o、 订单号,
v、 VendorName,
s、 状态名
从…起
命令
左外连接v打开
v、 Id=o.VendorId
左外部联接状态为“打开”
s、 Id=o.StatusId
哪里
o、 订单号>=100000和

o、 OrderNumber我认为你应该能够遵循post中使用的方法。看起来很难看,但我认为你可以做两次,然后得到你想要的结果


我想知道这是否真的是一种情况,您最好使用
DataContext.ExecuteCommand(…)
而不是转换为linq。

无法访问VisualStudio(我在Mac上),但使用其中的信息,您可能可以执行以下操作:

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 }

我了解了如何使用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
Dim db作为新的ContractDataContext()
Dim query=以db.顺序从o开始_
组加入数据库供应商_
关于v.VendorNumber等于o.VendorNumber_
进入ov=组_
从ov.DefaultIfEmpty()中的x开始_
组在数据库中加入。状态_
On s.Id等于o.StatusId进入os=组_
从os.DefaultIfEmpty()中的y开始_
其中o.OrderNumber>=100000和o.OrderNumber这可能更干净(您不需要将所有的
放入
语句中):

这里是另一个左连接示例

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  
    }

在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 

我将此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()
Dim result=(来自contractEntity.CSLogin.Where中的csL(函数(cs)cs.Login=Login,也就是cs.Password=Password)。DefaultIfEmpty

从contractEntity.UserType.Where中的usrT(函数(uTyp)uTyp.UserTypeID=csL.UserTyp).DefaultIfEmpty'@manitra:No,您实际上得到的是左外连接语句(没有嵌套选择)非常疯狂,是吧?比起使用所有的into语句,我更喜欢这种方法。谢谢你发布这篇文章!这真是太好了。但是:如果有连接,为什么linq中没有左连接?什么基于集合的世界只做内部连接?Grrr。这让我脸上挂起了一个大大的笑容。谢谢你简单易懂的示例。我尝试了这个,并且成功了比@tvanfosson的方法慢一个数量级。我不是直接针对数据库,而是严格按照linq对对象进行操作。我有500000个开销、4000个CategoryTos和4000个expenseTypeDtos。运行需要1分钟。使用tvanfosson的语法需要6秒。
 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()