Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 使用实体框架(core)在Linq中加入组后左连接_Entity Framework_Linq - Fatal编程技术网

Entity framework 使用实体框架(core)在Linq中加入组后左连接

Entity framework 使用实体框架(core)在Linq中加入组后左连接,entity-framework,linq,Entity Framework,Linq,问题:我想使用linq语法实体框架7在所需输出中生成下面的确切sql 问题的目标是生成下面的确切sql! 期望输出 我只能得到完全相同的sql,但有内部连接。我似乎无法得到两个左连接。下面的代码说明了我是如何生成内部连接的,以及生成左连接的失败尝试 SELECT [a].[AppUserId], [a].[FirstName], [a].[MiddleName], [a].[LastName], [a].[IsInternal], [a].[AspNetUserId], [a].[Picture

问题:我想使用linq语法实体框架7在所需输出中生成下面的确切sql

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

我只能得到完全相同的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]
具有内部联接的代码可以工作,但我需要左联接….: 带有左连接的代码…我缺少了一些概念,但不起作用 不起作用的是,在g2.RoleId等于d.Id的第3组行中,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();

这是一种使用非常糟糕的查询生成数据的变通方法。它会生成一系列对数据库的调用,这些调用会产生相同的结果集。然而,这绝对不是这份工作的最佳查询。我仍在等待RC2,我将更新答案

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

                           from c in _dbCtx.UserRoles
                           .Where(x => b!=null && x.UserId == b.Id)
                           .DefaultIfEmpty()

                           from d in _dbCtx.Roles
                             .Where(x => a !=null &&  x.Id == a.RoleId)
                             .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 = d.Name != null ? string.Empty :d.Name ,
                               SupervisorId = a.SupervisorId,
                               BackUpId = a.BackUpId,
                               HasAutoAssignClaims = a.HasAutoAssignClaims,
                               IsActive = a.IsActive

                           }).ToList();

如果我理解正确,您的问题是EF并没有生成左连接。若答案是肯定的,那个么解决方案非常简单,比如你们的实体应该有空属性

 public class SomeClass
    {
        public int Id { get; set; }
        public int? CategoryId { get; set; }
        public Category Category {get;set:}
    }
我脑子里有一个选择

_dbCtx.SqlQuery<T>(SqlStringHEre).ToList()
但当我们在评论中谈到IdentityUserRole并没有对role的引用时,这里有一个问题,所以让我们来解决这个问题。 创建类

 public class UserToRole : IdentityUserRole<int>
    {
        public Role Role { get; set; }
    }
如果有人来问这个问题,认为它还没有得到回答,那么答案现在就隐藏在问题后面的评论链中。我只是在这里转述主要的评论

问题是EntityFramework7目前是一个新的框架,并且有一些bug。其中一个bug导致OP记录的左连接失败


目前的解决方案是恢复到实体框架6,或者暂时使用存储过程或内联SQL,直到错误被修复。

您应该对此进行详细说明:我详细说明了一些概念,即当我在group3中使用g2.RoleId等于d.Id时,g2.RoleId不再可用。总体目标是在任何方法中用左连接复制上面的查询?从语法上看,这似乎是一个正确的语句。它给出了一个例外,即序列没有元素。这是因为在对它们进行分组后,它不再可供调用。您的LeftJoin查询是正确的。在EF6中,它会准确地生成您所期望的内容。在EF7 core中,它根本不起作用,这同样适用于许多其他有效的查询,所以我想说EF7还没有准备好使用。不幸的是,它生成的sql与我上面的查询不等价。其中也不包含在查询中非常重要的角色名称。它也不是最好的sql。记住,我想要的是生成我在上面的问题中提出的确切的sql。从[AspNetUserRoles]中选择[a].[UserId],[a].[RoleId]作为[a]内部联接从[AppUser]中选择DISTINCT*作为[apu]内部联接[AspNetUsers]作为[a]在[apu]上的[a]。[AspNetUserId]=[a0]。[Id]按[a].[Id]顺序排列@hidden你能解释为什么你需要完全相同的查询吗?因为我不敢相信不可能生成简单的左连接…我得到了内部连接等价物为什么做简单的左连接如此困难。如果你需要精确的sql,为什么不把sql放在一个存储过程中,然后从实体框架调用它?@hidden什么意思没有角色的属性_context.Users.Includeu=>u.roles我刚刚在我的项目中尝试过,它可以工作
_dbCtx.SqlQuery<T>(SqlStringHEre).ToList()
var query = _dbCtx.AppUser
.Include(apu=>apu.AspNetUser)
.Include(apu=>apu.AspNetUser.Roles)
.Include(apu=>apu.AspNetUser.Roles.Select(r=>r.Role))
.ToList();
 public class UserToRole : IdentityUserRole<int>
    {
        public Role Role { get; set; }
    }
 public class YourUser : IdentityUser<int, IdentityUserLogin<int>, UserToRole, IdentityUserClaim<int>>
_db.Users.Select(u=>u.Roles.Select(r=>r.Role.Name))