【发布时间】:2015-07-03 03:33:35
【问题描述】:
有没有办法对 EF 查询进行预编译,让应用无需编译(即使是第一次执行)?
我有很多复杂的查询,在使用 L2E 时需要一些时间来执行。例如,对于我对 Sql Server profiler 进行基准测试的一个查询报告大约 300 毫秒的执行时间,但实际上这个查询在我的 PC 上大约 4.5 秒后完成(至强四核 2.6 GHz 和 8 GB 的 RAM。这意味着我的 PC 正在等待数据到达大约 0.5 秒,并且花费大约 4 秒来编译和执行查询,最后读取我的 PC 上的数据(只有 4 条记录)。那是很多时间,特别是因为 ToListAsyncs() 不会将控制权返回给UI 直到实际查询被发送到数据库,这意味着我的应用程序在所有 4 秒内都“挂起”。解决此问题的一种方法是使用 Task.Run() 而不是 ToListAsync,但这只会让我的应用程序显示一些等待签到,还是会有4s的延迟。
在一些较旧的 PC 上,这可能意味着用户将等待 10 秒进行查询编译,这不是我们所希望的。那么,任何人都知道如何预编译所有查询,以便即使是第一次执行它们也不会延迟?
【问题讨论】:
-
实体框架 2011 年 6 月 CTP 支持称为自动编译的 LINQ 查询的新功能。现在,您自动执行的每个 LINQ to Entities 查询都会被编译并放置在 EF 的查询缓存中。每次运行查询时,EF 都会在其查询缓存中找到它,而不必再次执行整个编译过程。 blogs.msdn.com/b/efdesign/archive/2011/06/30/…如果你禁用了查询缓存,它将无法工作
-
@Legends 这不是一个真正的解决方案,原因有两个:1)在桌面应用程序中,某些查询一天只能执行一次 - 这意味着查询实际上永远不会被编译,2)大多数我的查询在 where 查询中包含 Enumerable.Contains。这在执行 SP 时可以正常工作,您可以在其中使用 TVP(在 EF 中支持),但是当使用 L2E 时,每次执行查询时都会生成一个新查询,因此没有自动查询编译。跨度>
-
我不是 EF Geek,但作为一种解决方法,我建议您在应用程序启动时异步预编译所有查询,例如,您有 30 个查询,但以这种方式排序,即最常用的首先编译,而不太常用的则在编译执行管道中稍后编译。客户端或服务器上的数据库在哪里?如果是服务器端,放弃LTE,使用纯T-SQL,这样执行计划就会缓存在db中。如果数据库在客户端,也许这也可以工作,但无法确认。
-
关键是在 L2E 查询中使用 Enumerable.Contains(...) 时无法编译它们,这是我在阅读该主题时才发现的。正如我在之前的评论中所说,TVP 可以在 EF6 中与 SP 一起正常工作,但为了可维护性,客户决定不使用 SP。
-
我有同样的问题:使用 EF6,我多次调用的查询没有预编译,需要很长时间才能完成。查询又长又复杂,我每次调用它时只调用它发送不同的输入参数(字符串)。我已经尝试了所有方法,但仍然无法正常工作(我没有调用 Enumerable.Contains(...) 这是唯一的限制。知道为什么吗?如此绝望,感谢任何帮助。
标签: entity-framework linq-to-entities entity-framework-6