c# - Entity Framework 和编译表达式性能

标签 c# entity-framework linq

我们正在使用 EF 进行数据访问,我们有这样的查询:

Expression<TTable, bool> expression = CreateSomeExpression();
var filter = finalExpression.Compile();
var results = db.t_Table.Where(filter).Select(x=>...);

我的问题是,EF 会在给定编译表达式的情况下构造正确的查询吗?

举个例子,如果我的表是:

t_Table 
( key int,
  value_1 varchar(30),
  value_2 varchar(30)
)

要编译的表达式是

p => p.value_1 = 100

这会(在 EF 中)转换为:

select * from t_Table where value_1 = 100

还是会翻译成

select * from t_Table

然后是对结果的 linq 查询?

有没有办法检查 EF 在数据库上实际调用了哪些 sql 查询?

非常感谢,

更新

虽然接受的答案是 100% 正确的(因此是接受的答案),但我的问题的解决方案是简单地删除编译。删除它会导致使用正确的 where 子句 进行正确的 SQL 查询。

最佳答案

您编译的表达式(生成一个类型为 Func<TTable, bool> 的委托(delegate)),事实上,导致表的完全加载,即

select * from t_Table

... 然后在将实体加载到内存中后对其进行过滤。

Entity Framework 只能将表达式(即Expression<Func<TTable, bool>>)翻译成SQL 查询。它无法反汇编已编译的委托(delegate) ( Func<TTable, bool> ) 随后将其转换为 SQL 查询。

这就是重载决议发挥作用的地方。 DbSet<T>同时实现 IQueryable<T>IEnumerable<T> .

  • 当您在 IQueryable<T> 上使用扩展方法时(并且它们中的大多数都接受表达式参数,即 Where<T>(Expression<Func<T, bool>>) ),您可以在数据库引擎中执行查询。

  • 每当您切换到 IEnumerable<T>扩展方法(即 Where<T>(Func<T, bool>)),EF 别无选择,只能将完整的实体集加载到内存中,然后像处理任何其他内存中集合一样迭代生成的缓存。

关于c# - Entity Framework 和编译表达式性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34674785/

相关文章:

c# - CompileToMethod 无法编译常量 '<some value>',因为它是一个不平凡的值,例如事件对象

c# - 如何以独立于区域设置的方式定位本地组?

c# - 在 web api 中编辑方法

LINQ:每组中最大计数的 GroupBy

entity-framework - 链接 Entity Framework Code First 模型中的两个表

C# - MVC 4 多对多复选框值传递给另一个 View

c# - 检查是否是 bool 值?在动态 Lambda 中为真

c# - 如何实现语法高亮方案?

c# - 将 PowerBuilder 应用程序移植到 .NET

c# - 为什么公司仍在使用 Windows 窗体和 WPF 应用程序而不是 Web 应用程序?