使用 linq 根据 Id 的列表选择多个记录

我有一个包含 UserProfile表 ID 的列表。我怎样才能选择所有的 UserProfiles的基础上的 ID 的列表,我在一个 var使用 LINQ

var idList = new int[1, 2, 3, 4, 5];
var userProfiles = _dataContext.UserProfile.Where(......);

我卡在这里了。我可以用 for 循环等来做这个,但是我更愿意用 LINQ来做这个。

267711 次浏览

你可以使用 Contains()。当你真正尝试产生一个 IN子句的时候,你会感觉有点后退,但是这个应该可以做到:

var userProfiles = _dataContext.UserProfile
.Where(t => idList.Contains(t.Id));

我还假设每个 UserProfile记录都有一个 int Id字段。如果情况不是这样的话,你就必须做出相应的调整。

应该很简单,试试这个:

var idList = new int[1, 2, 3, 4, 5];
var userProfiles = _dataContext.UserProfile.Where(e => idList.Contains(e));

解决方案。地点和。包含具有 O (N 平方)的复杂性。很简单。Join 应该有更好的性能(由于散列,接近 O (N))。所以正确的代码是:

_dataContext.UserProfile.Join(idList, up => up.ID, id => id, (up, id) => up);

现在是我测量的结果。我生成了100000个 UserProfiles 和100000个 id。加入花了32毫秒。在哪里。控制室花了2分19秒!在这个测试中,我使用了纯 IEnumable 来证明我的语句。如果使用 List 而不是 IEnumable,。地点和。控制会更快。不管怎样,差别是显著的。最快的。哪里。包含的内容是 Set < > 。所有这些都取决于基础集合的复杂性。包含。查看 这篇文章了解 linq 复杂性。看看下面我的测试样本:

    private static void Main(string[] args)
{
var userProfiles = GenerateUserProfiles();
var idList = GenerateIds();
var stopWatch = new Stopwatch();
stopWatch.Start();
userProfiles.Join(idList, up => up.ID, id => id, (up, id) => up).ToArray();
Console.WriteLine("Elapsed .Join time: {0}", stopWatch.Elapsed);
stopWatch.Restart();
userProfiles.Where(up => idList.Contains(up.ID)).ToArray();
Console.WriteLine("Elapsed .Where .Contains time: {0}", stopWatch.Elapsed);
Console.ReadLine();
}


private static IEnumerable<int> GenerateIds()
{
// var result = new List<int>();
for (int i = 100000; i > 0; i--)
{
yield return i;
}
}


private static IEnumerable<UserProfile> GenerateUserProfiles()
{
for (int i = 0; i < 100000; i++)
{
yield return new UserProfile {ID = i};
}
}

控制台输出:

已过期。联机时间: 00.00.0322546

经过。在哪里。包含时间: 00:02:19.4072107

不错的答案,但不要忘记一个 很重要的事情-他们提供不同的结果!

  var idList = new int[1, 2, 2, 2, 2]; // same user is selected 4 times
var userProfiles = _dataContext.UserProfile.Where(e => idList.Contains(e)).ToList();

这将从 DB 返回2行(如果您只想要一个不同的排序用户列表,这可能是正确的)

在许多情况下,您可能需要一个 未分类结果列表。您必须像思考 SQL 查询一样思考这个问题。请看购物车的例子来说明正在发生的事情:

  var priceListIDs = new int[1, 2, 2, 2, 2]; // user has bought 4 times item ID 2
var shoppingCart = _dataContext.ShoppingCart
.Join(priceListIDs, sc => sc.PriceListID, pli => pli, (sc, pli) => sc)
.ToList();

这将从 DB 返回 5结果。在这种情况下使用“包含”将是错误的。