Влияет ли порядок вызовов функций IEnumerable <T>на окончательный запрос при использовании Entity Framework? - PullRequest
0 голосов
/ 17 февраля 2010

В рамках сущности, будет ли заявление

MyDataContext.Products.OrderByDescending( (p) => p.Id ).GroupBy<Product,int>( (p) => p.ProductId ).Select( (g) => g.FirstOrDefault()).Where( (p) => p.Name.Equals("Something") );

результат в другом запросе к базе данных, чем

MyDataContext.Products.Where( (p) => p.Name.Equals("Something") ).OrderByDescending( (p) => p.Id ).GroupBy<Product,int>( (p) => p.ProductId ).Select( (g) => g.FirstOrDefault());

Другими словами, влияет ли порядок вызовов Where () и GroupBy () на окончательный запрос к БД? Или структура сущностей достаточно умна, чтобы решить эту проблему?

Причина, по которой я задаюсь вопросом, заключается в том, что в разрабатываемой системе нам необходимо отслеживать все изменения в ряду продуктов. Решение, которое мы используем для достижения этой цели, состоит в том, чтобы вставить новую строку продукта в таблицу, а не обновлять ее. Различные версии продукта затем группируются с помощью поля «ProductId». Таким образом, я хотел бы перенести логику «Группировка» на внешний метод, но при этом позволить вызывающей стороне указывать условия Where… поэтому моя цель - использовать первый подход.

1 Ответ

1 голос
/ 17 февраля 2010

Да, это важно. EF может беззвучно игнорировать OrderBy вызовы, поступившие до Where вызовов . Это не должно вызывать удивления, поскольку запросы SQL не поддерживают ORDER BY до WHERE вообще , вне подзапроса.

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

var q = SomeQuery
        .Where(GeneratePredicate())
        .GroupBy(GenerateSelector<string>());

Где у вас есть такие методы, как:

public Expresssion<Func<SomeEntity, bool>> GeneratePredicate
{
     return e => e.Id == 123;
}

public Expression<Func<SomeEntity, T>> GenerateSelector<T>()
{
     return e => e.GroupField;
}

Важно, что эти Where и GroupBy вызовы , а не методы IEnumerable<T>; это методы IQueryable<T>, поэтому они вообще могут быть преобразованы в SQL.

...