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

问题描述:

必须有一个更好的办法:LINQ表达对我来说看起来不合理:我的错误是什么?

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; 
     } 

能否请你告诉我的我的方法错误?

+0

你想完成什么? – Kixoka

+0

'我的错误是什么?' Igor

+0

不,代码没有错误,但是我的想法必然存在错误,因为肯定有更好的方法。这看起来很拙劣,我相当肯定我错过了一些明显的东西。 –

这应该做你想要什么:

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. 从产生枚举删除所有null秒。这是必要的,因为FirstOrDefault回报null如果没有匹配的用户发现
  4. 把我们的最终枚举成一个列表
+0

我想你忘了'ToList()'。 – NetMage

+0

@NetMage良好的捕获。 – stybl

+0

哈!看到?我确定必须有一个该死的更好的方法:)现在把这个,谢谢:)这看起来是一个很好的清洁剂。 –

我想你可以加入它,然后组,然后剔除分组。我不确定加入和分组是否具有前端加载的整体优势,因此您可能希望将秒表添加到此代码(以及您的原始代码)中,并找出一个。

我的建议是:

// 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(); 

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