实体框架不尊重懒惰的评估

时间:2012-05-17 12:39:05

标签: entity-framework

这有效:

var user = db.Users.OrderByDescending(u => u.Id).FirstOrDefault(u => u.Email == "asd@gmail.com" && u.Password == "8a79hjhfas8d7fd89");

它正确生成只返回一个用户的sql语句。

下面的代码在理论上是相同的,它带来了数据库中的所有用户,之后才应用过滤器。它就好像我正在做.ToList(),从而评估数据库中的所有内容,并在常规IEnumerable中应用过滤器,而不是生成正确的sql语句:

public static User Get(Func<User, bool> predicate)
{
  return db.Users.OrderByDescending(u => u.Id).FirstOrDefault(predicate);
}

var user = User.Get(u => u.Email == "asd@gmail.com" && u.Password == "8a79hjhfas8d7fd89");

这是实体框架上的错误还是我错过了什么?

2 个答案:

答案 0 :(得分:1)

您正在传递Func<>,这是一个已编译的委托。相反,您应该传入Expression<>作为Get参数,这是一个语法树,EF可以分析并生成查询,而不是针对每个结果执行委托方法。

答案 1 :(得分:0)

EF不知道如何将任意Func委托转换为SQL,因此除了加载整个数据集然后在该结果集上运行谓词之外别无选择。