2

我有以下表格,这些表格来自我的带有实体框架 5 的 SQL 数据库。

我想要做的是选择 tblUserBusiness.BUID 等于传入值或 Users.IsSysAdmin 等于 True 的所有用户。如果 Users.IsSysAdmin 等于 True,则不会有相关的 tblUserBusiness 记录,因此是 Left Outer Join。

在此处输入图像描述

我从以下 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

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

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

3 回答 3

2

尝试这个:

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

任何一个都会给你你需要的东西。我认为 :)

于 2013-06-13T19:00:27.460 回答
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可以在 VB.NET 中使用DefaultIfEmptyand FirstOrDefault(这是可选的,有助于以一种很好的方式组织数据)。

于 2013-06-13T14:53:37.627 回答
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))

试图在评论中发布,但完整的代码没有正确显示

于 2020-02-03T08:31:53.543 回答