Почему анализатор LINQ EntityFramework по-другому обрабатывает внешне определенный предикат?

Я использую Microsoft Entity Framework в качестве 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());

Это также работает с точки зрения кода, поскольку возвращает тот же Продукт установлено, но на этот раз созданный SQL аналогичен следующему:

SELECT * FROM Product;

Фильтр перемещен с SQL Server на клиент, что значительно снижает его эффективность.

У меня следующие вопросы:

  • Почему это происходит, почему синтаксический анализатор LINQ так по-разному обрабатывает эти два формата?
  • Что я могу сделать, чтобы воспользоваться преимуществом разделения фильтра, но выполнения его на сервере ?
9
задан Kamil Budziewski 16 August 2013 в 10:30
поделиться