我有一个包含UserProfile
表ID的列表。我如何可以选择所有UserProfiles
的基于身份的名单我在得到上var
使用LINQ
?
var idList = new int[1, 2, 3, 4, 5];
var userProfiles = _dataContext.UserProfile.Where(......);
我被困在这里。我可以使用for循环等执行此操作。但是,我宁愿使用LINQ
。
我有一个包含UserProfile
表ID的列表。我如何可以选择所有UserProfiles
的基于身份的名单我在得到上var
使用LINQ
?
var idList = new int[1, 2, 3, 4, 5];
var userProfiles = _dataContext.UserProfile.Where(......);
我被困在这里。我可以使用for循环等执行此操作。但是,我宁愿使用LINQ
。
Answers:
您可以使用Contains()
它。当您真正尝试生成IN
子句时,会感到有些倒退,但是应该这样做:
var userProfiles = _dataContext.UserProfile
.Where(t => idList.Contains(t.Id));
我还假设每个UserProfile
记录将有一个int
Id
字段。如果不是这种情况,则必须进行相应调整。
Contains()
id
如果您按照我在答案中所写的那样使用每个值,将处理该相等性检查。==
当您尝试将一组(数组)的项目与另一组(数据库表)的项目进行比较时,无需在任何地方显式编写。
使用.where和.contains的解决方案具有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花了32毫秒,而.Where和.Contains花了2分19秒!我在测试中使用了纯IEnumerable来证明我的陈述。如果使用List而不是IEnumerable,则.Where和.Contains将更快。无论如何,差异是显着的。最快的。包含.Set。所有这些都取决于.Contains的底层完成的复杂性。查看这篇文章以了解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:00.0322546
经过的时间,包含时间:00:02:19.4072107
List
。+1
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
使用LINQ2SQL的DataContext时错误。
很好的回答,但不要忘记一件重要的事-它们提供不同的结果!
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个结果。在这种情况下,使用“包含”将是错误的。
那应该很简单。试试这个:
var idList = new int[1, 2, 3, 4, 5];
var userProfiles = _dataContext.UserProfile.Where(e => idList.Contains(e));