Я использую Entity Framework от Microsoft в качестве ORM, и мне интересно, как решить следующую проблему.
Я хочу получить количество Product
объектов из коллекции Products
, где 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 так по-разному относится к этим двум форматам?
- Что я могу сделать, чтобы использовать фильтр отдельно, но при его запуске на сервере?