LINQ左外连接条件

时间:2013-06-13 14:47:54

标签: .net vb.net linq linq-to-entities

我有以下表格来自我的SQL数据库和实体框架5。

我想要做的是选择tblUserBusiness.BUID等于传入值的所有用户或者Users.IsSysAdmin等于True的用户。如果Users.IsSysAdmin等于True,则没有相关的tblUserBusiness记录因此左外连接。

enter image description here

我从以下LINQ查询开始,该查询已正确过滤但不允许外部联接

        businessUsers = (From u In db.Users
                            From bu In db.tblUserBusinesses
                            Where bu.BUID.Equals(buID) Or u.IsSysAdmin.Equals(True)
                                Select New Users With {.ID = u.ID,
                                                       .Name = u.Name,
                                                       .UserName = u.UserName}).ToList

然后我转到下面的查询,允许外部加入,但我不知道如何实现Where bu.BUID.Equals(buID) Or u.IsSysAdmin.Equals(True)

        businessUsers = (From u In db.Users
                            Group Join bu In db.tblUserBusinesses
                                On u Equals bu.User
                                Into userList = Group
                         Select New Users With {.ID = u.ID,
                                                       .Name = u.Name,
                                                       .UserName = u.UserName}).ToList

基本上我所追求的是LINQ等同于以下TSQL

SELECT Users.ID, Users.UserName, Users.Name 
    FROM Users LEFT OUTER JOIN tblUserBusiness ON Users.ID = tblUserBusiness.UserID
    WHERE (Users.IsSysAdmin = 1) OR (tblUserBusiness.BUID = 5)

3 个答案:

答案 0 :(得分:1)

试试这个:

Dim buID As Integer = ... ' BUID to get

Dim q = From u In Users
        Group Join bu In tblUserBusiness On u.Id Equals bu.UserID Into Group
        From j In Group.DefaultIfEmpty
        Where u.IsSysAdmin OrElse If(j IsNot Nothing, j.BUID = buID, False)
        Select u

......或......

Dim q = From u In Users
        Group Join bu In tblUserBusiness On u.Id Equals bu.UserID Into Group
        From j In Group.Where(Function(x) x.BUID = buID).DefaultIfEmpty
        Where u.IsSysAdmin OrElse j IsNot Nothing
        Select u

任何一个都能满足您的需求。我想:))

答案 1 :(得分:0)

您需要使用DefaultIfEmpty,因此它应该是

Group Join bu In db.tblUserBusinesses.DefaultIfEmpty

这是一个简化的测试用例(需要一个全新的控制台应用程序):

Module Module1
  Class Person
    Public Property Id As String
    Public Property FirstName As String
  End Class

  Class Address
    Public Property Id As String
    Public Property StreetName As String
  End Class

  Sub Main()
    Dim personList As New List(Of Person)
    With personList
      .Add(New Person With {.Id = "1", .FirstName = "John"})
      .Add(New Person With {.Id = "2", .FirstName = "Peter"})
      .Add(New Person With {.Id = "3", .FirstName = "Victor"})
    End With

    Dim addressList As New List(Of Address)
    With addressList
      .Add(New Address With {.Id = "1", .StreetName = "Baker Street"})
      .Add(New Address With {.Id = "2", .StreetName = "Broadway"})
      .Add(New Address With {.Id = "4", .StreetName = "Hwy 999"})
    End With

    Dim v = From p In personList
            Group Join a In addressList.DefaultIfEmpty
            On a.Id Equals p.Id Into Group
            Select PersonId = p.Id,
                   PersonName = p.FirstName,
                   StreetName = Group.FirstOrDefault
  End Sub
End Module

虽然这可能不是人与地之间关系的理想设计,但它证明Outer Join可以使用DefaultIfEmptyFirstOrDefault在VB.NET中工作(这是可选的) ,帮助您以一种美好的方式组织数据。

答案 2 :(得分:0)

+1代表@ajakblackgoat答案。谢谢兄弟,它帮助了我!但是,我是C#开发人员,所以如果其他类似我的开发人员登陆此页面,请为其发布 C#版本

from u in Users
join bu in tblUserBusiness on u.Id equals bu.UserID into group
from j in group.DefaultIfEmpty()
where (u.IsSysAdmin || (j != null ? j.BUID == buID : false))

试图发表评论,但完整代码未正确显示