我正在寻找一种以Contains()可扩展的方式执行语句的优雅方式.在我提出实际问题之前,请允许我给出一些背景知识.
IN声明在Entity Framework和LINQ to SQL中,该Contains语句被翻译为SQL IN语句.例如,从这个声明:
var ids = Enumerable.Range(1,10);
var courses = Courses.Where(c => ids.Contains(c.CourseID)).ToList();
Run Code Online (Sandbox Code Playgroud)
实体框架将生成
SELECT
[Extent1].[CourseID] AS [CourseID],
[Extent1].[Title] AS [Title],
[Extent1].[Credits] AS [Credits],
[Extent1].[DepartmentID] AS [DepartmentID]
FROM [dbo].[Course] AS [Extent1]
WHERE [Extent1].[CourseID] IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Run Code Online (Sandbox Code Playgroud)
不幸的是,该In声明不具备可扩展性.根据MSDN:
在IN子句中包含极大数量的值(数千)可能会消耗资源并返回错误8623或8632
这与资源耗尽或超出表达限制有关.
但是在这些错误发生之前,IN随着项目数量的增加,语句变得越来越慢.我无法找到有关其增长率的文档,但它可以很好地执行数千个项目,但除此之外它会变得非常缓慢.(基于SQL Server经验).
我们不能总是避免这种说法.JOIN具有源数据的A 通常会执行得更好,但这仅在源数据处于相同上下文时才有可能.在这里,我正在处理来自断开连接的场景中的客户端的数据.所以我一直在寻找可扩展的解决方案.一个令人满意的方法是将操作切成块:
var courses = ids.ToChunks(1000)
.Select(chunk …Run Code Online (Sandbox Code Playgroud)