我正在使用 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/