【发布时间】:2016-01-14 08:31:33
【问题描述】:
Entity Framework 5+ 应该预编译所有查询。但是,对于诸如
之类的查询List<Guid> ids;
var entities = context.MyEntities.Where(x => ids.Contains(x.Id)).ToArray();
Entity Framework 无法对查询进行预编译,根据整体查询的复杂程度,将表达式树解析为 SQL 可能需要几秒钟的时间。有没有人找到解决方法来获得预编译的查询?我真的不明白为什么会这么难;当然,参数很难处理,因为元素的数量可能不同,但有类似 SQL 就足够了
SELECT a, b, c from MyEntities
WHERE c in __PLACEHOLDER__
然后用实际的列表元素替换占位符。当然,它不如传递参数那么好,但它比等待几秒钟来一遍又一遍地解析整个表达式树要好得多。
【问题讨论】:
-
列表不能用作参数,因此它会按照您的建议进行操作,即构造一个新查询,因为您的列表每次调用时都可以包含不同的元素。所以它实际上是一个 SQL 限制。
-
不完全;如前所述,它每次都从头开始解析表达式树。我们有一个包含几个连接的查询,解析需要 5 秒(在 sql server 上需要几毫秒),这就是我正在寻找解决方法的原因。
-
@roland 这个列表有多大?你也必须使用包含吗?问题可能取决于每个条目的长度......他需要比较多少。在我使用 StringComparison.Ordinal 之前,我在 .StartsWith 上遇到了类似的问题,这大大加快了速度(与 .Contains 相比)。问题可能只是他需要遍历太大的字符串(太大需要时间)。如果您可以将其更改为 startswith 和 ordinal 它应该会大大加快(但取决于您的确切用例)。
-
包含的问题只是.....sql 服务器是为这种类型的搜索而设计的,并针对它进行了优化,而 c# 无法在该领域使用它们。也许最好重组你的 sql 以在 sql 中搜索这些?
-
@Eldho:我对这篇文章很熟悉,我说的是表达式树的解析确实需要几秒钟的情况,即没有编译我们就会崩溃。
标签: c# entity-framework contains enumerable