表现:.Join vs .Contains – Linq to Entities

我使用Linq实体查询数据库以获取int列表以供进一步处理。 我有两种方法可以获得如下列表:

首先是:

List lstBizIds = new List() { 1, 2, 3, 4, 5 }; List lstProjectIds = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList(); 

第二是:

 List lstBizIds = new List() { 1, 2, 3, 4, 5 }; List lstProjectIds = context.Projects.Join(lstBizIds, p => p.businessId, u => u, (p, u) => p.projectId).ToList(); 

现在我的问题是上面哪一种方法更好的表现? 如果第一个列表即lstBizIds的大小增加,它是否也会影响性能? 如果性能降低,建议我采用其他实施方式。

你应该使用Contains ,因为EF可以产生更有效的查询。

这将是SQL连接:

 SELECT Id FROM Projects INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item 

这将是SQL包含:

 SELECT Id FROM Projects WHERE UserId IN (1, 2, 3, 4, 5, 6) 

INJOIN更有效,因为DBMS可以停止查看IN的第一个匹配; 即使在第一场比赛之后, JOIN也会一直结束。

您可能还想检查哪些查询实际发送到数据库。 你总是需要比较SQL,而不是LINQ代码(显然)。

执行连接非常有效,因为Where条件实际执行所有表的笛卡尔积,然后过滤满足条件的行。 这意味着为每个行组合评估Where条件(n1 * n2 * n3 * n4)

Join运算符从第一个表中获取行,然后仅获取第二个表中具有匹配键的行,然后仅获取第三个表中具有匹配键的行,依此类推。 其次,contains会以迭代的方式工作,使得它比join更慢

我选择第一个,因为它不会增加计算机的内存。
如果您使用两个数组来比较条件,请从第二个选择。

我花了很长时间试图找到,导致程序中的堆栈溢出错误的原因是一些简单的LINQ查询访问中型数据库。

对于ICollection,一边是~10k元素,另一边是sql表,从“join”到“Contains”的单个更改修复了堆栈溢出错误。

似乎尽管有比较性能,Contains是一个更安全的选择。