LINQ语句对我来说看起来不合理:我的错误是什么?

时间:2017-08-16 18:09:09

标签: c# asp.net linq asp.net-identity

必须有更好的方法:

public IList<ApplicationUser> GetProspects()
        {
            var UsrNames = Roles.GetUsersInRole("prospect");
            IList<ApplicationUser> Users = new List<ApplicationUser>();

            foreach ( var u in UsrNames)
            {
                // In theory should return at most one element. 
                var UserListFromQuery = from usr in (new ApplicationDbContext()).Users where usr.UserName == u select usr;
                Users.Add(UserListFromQuery.ElementAtOrDefault(0));
            }
            return Users;
        }

你能告诉我我的方式错误吗?

2 个答案:

答案 0 :(得分:2)

这应该做你想要的:

using (var context = new ApplicationDbContext())
{
    var result = Roles.GetUsersInRole("prospect")
                      .Select(name => context.Users.FirstOrDefault(user => user.UserName == name))
                      .Where(user => user != null)
                      .ToList();
}

我已修改您的代码,以便为上下文使用using语句,以确保即使存在异常也会正确处理它。然后我有一个linq查询,它执行以下操作:

  1. 获取用户名
  2. 对于每个用户名,请选择Users中具有匹配用户名
  3. 的第一个用户
  4. 从生成的枚举中删除所有null。这是必要的,因为如果找不到匹配的用户,FirstOrDefault将返回null
  5. 将我们的最终枚举转换为列表

答案 1 :(得分:1)

我想你可以加入它,然后分组,然后剔除分组。我不确定您是通过加入和分组来实现前端加载的整体优势,所以您可能想要为此(以及您的原始代码)设置一个秒表并计算那一个。

我的建议是:

// force a prefetch, rather than potentially slamming the server again and again
var allUsers = (new ApplicationDbContext()).Users.ToList(); 

// use the prefetched list to join & filter on
var result = from entitled in UsrNames 
          join user in allUsers
          on entitled equals user.UserName
          group user by user.UserName into grp
          select grp.First();

return result.ToList();

几个想法: 这显然是一个与用户相关的表。因此,我猜测你不会有那么多的100k记录。最多可能有数千人。因此可以安全地缓存在本地内存中,特别是如果数据在一天中不会多次更改。如果这是真的,您甚至可能希望在之前预先加载集合,并将其存储到数据的单个实例中,以便稍后重用。但是,如果数据很少发生变化,这种观察结果才会成立。