LINQ有条件的左外连接

问题描述 投票:2回答:3

我具有来自带有实体框架5的SQL数据库的下表。

[我想做的是选择所有用户,其中tblUserBusiness.BUID等于传入的值,或者其中Users.IsSysAdmin等于True。如果Users.IsSysAdmin等于True,那么将没有相关的tblUserBusiness记录,因此将是“左外部联接”。

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9VdW9ZWS5wbmcifQ==” alt =“在此处输入图像描述”>

我从下面的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)
.net vb.net linq linq-to-entities
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

任何人都会给您您所需要的。我认为:)

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中工作(可选,可帮助您在漂亮时尚)。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.