Joe*_*ett 9 .net c# linq entity-framework sql-generation
我正在使用Microsoft的Entity Framework作为ORM,我想知道如何解决以下问题.我想Product从Products集合中获得Product.StartDate比当今更大的对象.(这是整个问题的简化版本.)
我目前使用:
var query = dbContext.Products.Where(p => p.StartDate > DateTime.Now);
Run Code Online (Sandbox Code Playgroud)
执行此操作时,在使用ToList()例如查询后,它可以正常工作,并且创建的SQL是有效的:
SELECT * FROM Product WHERE StartDate > (GetDate());
Run Code Online (Sandbox Code Playgroud)
但是,我想将谓词移动到一个函数以获得更好的可维护性,所以我尝试了这个:
private Func<Product, bool> GetFilter()
{
Func<Product, bool> filter = p => p.StartDate > DateTime.Now;
return filter;
}
var query = dbContext.Products.Where(GetFilter());
Run Code Online (Sandbox Code Playgroud)
这也是从代码的角度来看,只要它返回相同的Product集合,但这次创建的SQL类似于:
SELECT * FROM Product;
Run Code Online (Sandbox Code Playgroud)
筛选器从SQL Server移动到客户端,使其效率降低.
所以我的问题是:
您需要使用Expression<Func<Product, bool>>它才能使其像您想要的那样工作.普通Func<Product, bool>告诉LINQ你希望它Where在你的程序中运行MSIL而不是SQL.这就是为什么SQL会拉入整个表,然后你的.NET代码在整个表上运行谓词.
您正在返回一个Func,但要将谓词注入到 SQL 中,LINQ 需要表达式树。如果您将方法(当然还有局部变量)的返回类型更改为Expression<Func<Product, bool>>.