c# - 为什么 EntityFramework 的 LINQ 解析器以不同方式处理外部定义的谓词?

标签 c# .net linq entity-framework sql-generation

我正在使用 Microsoft 的 Entity Framework 作为 ORM,想知道如何解决以下问题。 我想从 Products 集合中获取一些 Product 对象,其中 Product.StartDate 大于今天。 (这是整个问题的简化版本。)

我目前使用:

var query = dbContext.Products.Where(p => p.StartDate > DateTime.Now);

执行此操作时,例如在查询中使用 ToList() 后,它会起作用并且创建的 SQL 有效:

SELECT * FROM Product WHERE StartDate > (GetDate());

但是,为了更好的可维护性,我想将谓词移动到一个函数中,所以我尝试了这个:

private Func<Product, bool> GetFilter()
{
  Func<Product, bool> filter = p => p.StartDate > DateTime.Now;
  return filter;
}
var query = dbContext.Products.Where(GetFilter());

从代码的角度来看,这也是可行的,因为它返回相同的 Product 集,但这次创建的 SQL 类似于:

SELECT * FROM Product;

过滤器从 SQL Server 移动到客户端,使其效率大大降低。

所以我的问题是:

  • 为什么会这样,为什么 LINQ 解析器对这两种格式的处理如此不同?
  • 如何利用单独的过滤器但在服务器上执行它的优势?

最佳答案

您需要使用 Expression<Func<Product, bool>>为了让它像你想要的那样工作。一个普通的Func<Product, bool>告诉 LINQ 您希望它运行 Where在程序中的 MSIL 中,而不是在 SQL 中。这就是 SQL 提取整个表,然后您的 .NET 代码在整个表上运行谓词的原因。

关于c# - 为什么 EntityFramework 的 LINQ 解析器以不同方式处理外部定义的谓词?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8969016/

相关文章:

.net - 预览 .NET 颜色

c# - Linq 帮助。 int.Contains 和 int == iqueryable 不起作用

linq - LINQ 不支持使用本地集合的查询

c# - 非顺序列表绑定(bind)不起作用

c# - .NET 局部变量优化

c# - Entity Framework 正在生成返回整个表的 SQL

c# - 阅读没有签名的正文

C#调用具有复杂结构的deviceIOControl

c# - 在 foreach 循环中修改对象的值

c# - 在自定义 Html Helper 中获取 Action 的 MvcHtmlString