entity-framework - 使用 Entity Framework (核心)在 Linq 中进行左连接

标签 entity-framework linq

问题:我想使用 linq 语法( Entity Framework 7)在所需输出中生成下面的确切 sql

问题的目标是生成下面的精确 SQL! 期望输出

select a.AppUserId, u.Email, a.FirstName, a.MiddleName, a.LastName, a.IsInternal, a.AspNetUserId, a.PictureLink, a.SignatureLink, a.PhoneNumber, a.Extension, a.FaxNumber, a.MobileNumber, a.Skype, r.Name as 'Role', a.SupervisorId, a.BackUpId, a.HasAutoAssignClaims, a.IsActive
from AppUser a
join AspNetUsers u on a.AspNetUserId = u.Id
left join AspNetUserRoles ur on u.Id = ur.UserId
left join AspNetRoles r on ur.RoleId = r.Id

我只能获得完全相同的 sql,但具有内部联接。我似乎无法获得两个左连接。下面的代码是我如何生成内部连接以及生成左连接的失败尝试。

SELECT [a].[AppUserId], [a].[FirstName], [a].[MiddleName], [a].[LastName], [a].[IsInternal], [a].[AspNetUserId], [a].[PictureLink], [a].[SignatureLink], [a].[PhoneNumber], [a].[Extension], [a].[FaxNumber], [a].[MobileNumber], [a].[Skype], [a].[SupervisorId], [a].[BackUpId], [a].[HasAutoAssignClaims], [a].[IsActive]
FROM [AppUser] AS [a]
INNER JOIN [AspNetUsers] AS [b] ON [a].[AspNetUserId] = [b].[Id]
INNER JOIN [AspNetUserRoles] AS [c] ON [b].[Id] = [c].[UserId]
INNER JOIN [AspNetRoles] AS [d] ON [a].[RoleId] = [d].[Id]

带有内连接的代码可以工作,但我想要左连接......:

 var query = (
                              //INNER JOIN 
                              from a in _dbCtx.AppUser
                              join b in _dbCtx.Users
                              on a.AspNetUserId equals b.Id 


                              ////LEFT JOIN
                              join c in _dbCtx.UserRoles
                              on b.Id equals c.UserId 

                              //    //    //LEFT JOIN  (if you wanted right join the easiest way is to flip the order of the tables. 
                              join d in _dbCtx.Roles
                              on a.RoleId equals d.Id





                          select new
                          {
                              AppUserId = a.AppUserId,
                              //Email = b.Email,
                              FirstName = a.FirstName,
                              MiddleName = a.MiddleName,
                              LastName = a.LastName,
                              IsInternal = a.IsInternal,
                              AspNetUserId = a.AspNetUserId,
                              PictureLink = a.PictureLink,
                              SignatureLink = a.SignatureLink,
                              PhoneNumber = a.PhoneNumber,
                              Extension = a.Extension,
                              FaxNumber = a.FaxNumber,
                              MobileNumber = a.MobileNumber,
                              Skype = a.Skype,
                              //Role = d.Name != null ? string.Empty :d.Name ,
                              SupervisorId = a.SupervisorId,
                              BackUpId = a.BackUpId,
                              HasAutoAssignClaims = a.HasAutoAssignClaims,
                              IsActive = a.IsActive

                          }).ToList();

使用 Left Join 的代码...我缺少一些概念不起作用

不起作用的是,在 g2.RoleId 等于 d.Id 到 group3 行上,g2 不可用。那么我如何使 c.RoleId 可用于我的下一个左连接?基本上,在你对某些东西进行分组后,你显然不能再使用它。

        var LeftJoin= (
                          //INNER JOIN 
                          from a in _dbCtx.AppUser
                          join b in _dbCtx.Users
                          on a.AspNetUserId equals b.Id 


                          ////LEFT JOIN
                          join c in _dbCtx.UserRoles
                          on b.Id equals c.UserId into group2
                          from g2 in group2.DefaultIfEmpty() //makes it left join 



                          join d in _dbCtx.Roles
                          on g2.RoleId equals d.Id into group3
                          from g3 in group3.DefaultIfEmpty()

                          select new
                          {
                              AppUserId = a.AppUserId,
                              Email = b.Email,
                              FirstName = a.FirstName,
                              MiddleName = a.MiddleName,
                              LastName = a.LastName,
                              IsInternal = a.IsInternal,
                              AspNetUserId = a.AspNetUserId,
                              PictureLink = a.PictureLink,
                              SignatureLink = a.SignatureLink,
                              PhoneNumber = a.PhoneNumber,
                              Extension = a.Extension,
                              FaxNumber = a.FaxNumber,
                              MobileNumber = a.MobileNumber,
                              Skype = a.Skype,
                              Role = g3.Name != null ? string.Empty :g3.Name ,
                              SupervisorId = a.SupervisorId,
                              BackUpId = a.BackUpId,
                              HasAutoAssignClaims = a.HasAutoAssignClaims,
                              IsActive = a.IsActive

                          }).ToList();

enter image description here

最佳答案

如果有人提出这个问题,认为它还没有得到解答,答案目前隐藏在问题后面的评论链中。我只是解释一下这里的关键评论。

问题是 Entity Framework 7 目前是 release candidate并且有一些错误。这些错误之一 ( Left Join doesn't work if the filter is composed on top ) 导致 OP 指出的左连接失败。

目前的解决方案是恢复到 Entity Framework 6,或暂时使用存储过程或内联 SQL,直到修复错误。

关于entity-framework - 使用 Entity Framework (核心)在 Linq 中进行左连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35493961/

相关文章:

c# - 如何删除Linq to Entity中的多条记录?

c# - 我在 Entity Framework 中放置条件的顺序有关系吗

c# - LINQ 表达式返回 null

c# - Entity Framework 代码优先 + MySQL...NullReferenceException

c# - linq where 子句和计数导致空异常

c# - Webapi 计算特定的获取请求

asp.net-mvc - 我如何使用 FirstOrDefault()?

c# - 在 LINQ 中使用 MIN 函数

c# - 没有存储库模式的 ASP.Net MVC 和 Entity Framework 项目架构

c# - 使用 LINQ 对 DataTable 进行 LIKE 查询