我们使用EF进行数据访问,我们有这样的查询:
Expressionexpression = 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%正确的(因此是接受的答案),但我的问题的解决方案是简单地删除编译.删除它导致正确的SQL查询正确where clause
.
事实上,您编译的表达式(导致类型的委托Func
)将导致表上的满载,即
select * from t_Table
...然后在将实体加载到内存后对其进行过滤.
实体框架只能将表达式(即Expression
)转换为SQL查询.它不能反汇编已编译的委托(Func
)以便随后将其转换为SQL查询.
这是重载决议发挥作用的地方.DbSet
实现IQueryable
和IEnumerable
.
当您使用扩展方法IQueryable
(并且大多数接受表达式参数,即Where
)时,您将在数据库引擎中执行查询.
每当您切换到IEnumerable
扩展方法(即Where
)时,EF别无选择,只能将完整的实体集加载到内存中,然后像生成任何其他内存中集合一样迭代生成的缓存.