实体框架和编译表达式的性能

本文关键字:性能 表达式 编译 框架 实体 | 更新日期: 2023-09-27 18:29:26

我们使用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在DB上实际调用的sql查询?

非常感谢,

更新

虽然公认的答案是100%正确的(因此是公认的答案),但我的问题的解决方案是简单地删除汇编。删除导致了具有正确where clause的正确SQL查询。

实体框架和编译表达式的性能

您编译的表达式(导致类型为Func<TTable, bool>的委托)实际上会导致表上的满负载,即

select * from t_Table

然后在将实体加载到存储器中之后对其进行过滤。

实体框架只能将表达式(即Expression<Func<TTable, bool>>)转换为SQL查询。它无法反汇编已编译的委托Func<TTable, bool>)以随后将其转换为SQL查询。

这就是过载解决方案发挥作用的地方。CCD_ 5实现了CCD_ 6和CCD_。

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

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