根据linq的ID列表select多个logging

我有一个包含我的UserProfile表的Id的列表。 我如何可以select所有的用户UserProfiles基于我使用LINQvar的列表?

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

我在这里卡住了 我可以使用for循环等,但我宁愿这样做与LINQ

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

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

我还假设每个UserProfilelogging将有一个int Id字段。 如果不是这种情况,你将不得不相应调整。

.Where和.Contains的解决scheme的复杂度为O(N square)。 简单。join应该有更好的性能(由于哈希接近O(N))。 所以正确的代码是:

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

现在我的测量结果。 我生成了100 000个UserProfiles和100 000个ID。 join了32ms和.Where .Contains花了2分19秒! 我用纯IEnumerable进行这个testing来certificate我的说法。 如果使用List而不是IEnumerable,那么.Where和.Contains会更快。 无论如何,差异是显着的。 最快的.Where .Contains是与Set <>。 所有这一切都取决于.Contains的基本coletions的复杂性。 看看这篇文章 ,了解linq复杂性。查看下面的testing示例:

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

控制台输出:

已join时间:00:00:00.0322546

包括时间:00:02:19.4072107

这应该很简单。 尝试这个:

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

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

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

这将从数据库返回2行(这可能是正确的,如果你想只是不同的清理用户列表)

在很多情况下,你可能想要一个没有列出的结果列表。 你总是不得不考虑一下SQL查询。 请参阅eshop购物车示例来说明发生了什么事情:

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

这将从数据库返回5个结果。 在这种情况下使用'contains'将是错误的。