Asp.net 为什么在获取用户列表时获取角色如此缓慢?

Asp.net 为什么在获取用户列表时获取角色如此缓慢?,asp.net,.net,asp.net-web-api2,asp.net-identity,Asp.net,.net,Asp.net Web Api2,Asp.net Identity,我正在获取数据库中的所有用户及其关联角色。它能工作,但人是慢的 var ctx = new SiteUserContext(); var ctxUserList = ctx.Users.ToList(); //var userManager = new UserManager<SiteUser>(new UserStore<SiteUser>(new SiteUserContext())); var j

我正在获取数据库中的所有用户及其关联角色。它能工作,但人是慢的

        var ctx = new SiteUserContext();
        var ctxUserList = ctx.Users.ToList();


        //var userManager = new UserManager<SiteUser>(new UserStore<SiteUser>(new SiteUserContext()));

        var jsonModels = from user in ctxUserList
                         select new
                         {
                             userName = user.UserName,
                             Roles = (from userRole in user.Roles
                                      join role in ctx.Roles on userRole.RoleId
                                      equals role.Id
                                      select role.Name).ToList(),
                             id = user.Id
                         };
var ctx=newsiteusercontext();
var ctxUserList=ctx.Users.ToList();
//var userManager=newusermanager(newuserstore(newsiteusercontext());
var jsonModels=来自ctxUserList中的用户
选择新的
{
userName=user.userName,
角色=(来自user.Roles中的userRole
在userRole.RoleId上的ctx.Roles中加入角色
等于角色Id
选择role.Name).ToList(),
id=user.id
};
只需要一个用户列表就可以了,100个用户大约600毫秒。但一旦我尝试加入角色,我就会等待5-10秒。每个用户只有1或2个角色。这并不是一个大问题

我尝试使用userManager
GetRolesById(user.Id)
,但速度更慢。10秒以上


如果您有任何关于快速运行的建议,我们将不胜感激。

您在这里执行N+1查询以获取信息,因为您获得了用户列表,然后枚举用户列表以简化流程。使用LINQ,我们可以更有效地完成这项工作。我以前在一个过程中使用过这个

var usersWithRoles = (from user in ctx.Users  
                      select new  
                       {  
                        UserId = user.Id,                                        
                        Username = user.UserName,  
                        Email = user.Email,  
                        RoleNames = (from userRole in user.Roles  
                                     join role in context.Roles on userRole.RoleId   
                                     equals role.Id  
                                     select role.Name).ToList()  
                                  })
                    .ToList()
                    .Select(p => new   
                    {  
                       UserId = p.UserId,  
                       Username = p.Username,  
                       Email = p.Email,  
                       Role = string.Join(",", p.RoleNames)  
                    });  
这应该要快得多,只需一个查询就可以实现


编辑:查看您的请求,如果您只想将角色作为列表,可以跳过本例中的第二个投影。(我需要在列表中显示它,因此在示例中是string.Join。

您正在对角色进行列表。这将为每个用户添加一个额外的查询。因此,您从一个查询转到n个查询,其中“n=用户数”我通常会尝试将这种复杂的逻辑排除在Linq之外。但我想您可能需要某种连接。听起来我可能需要使用存储过程来快速完成这项工作,而不是依赖EF。令人失望的是,您应该能够使用EF/Linq来完成这项工作。您只需要进行连接。它处理查询的方式并不直观恩,你试着像我一样将其拆分。你做了基本相同的事情,你只是将角色部分聚集到获取用户部分。我会假设它仍然会迭代用户以获取角色。我的假设是两次查询而不是一次。不是一次查询vs N次。有趣,谢谢你的回答!@cphilpot遗憾的是,由于延迟执行的工作方式,这是EF运行方式无法完全理解的最常见的领域之一。我很高兴这让它为您工作。令人惊讶的是,通过进行增量更改,您可以实现极快的更改。