Я использую T4 для создания репозиториев для сущностей LINQ to Entities.
Репозиторий содержит (среди прочего) метод List, подходящий для пейджинга. В документации по Поддерживаемые и неподдерживаемые методы это не упоминается, но вы не может «вызвать» Skip
неупорядоченный IQueryable
. Это вызовет следующее исключение:
System.NotSupportedException: метод «Пропустить» поддерживается только для отсортированного ввода в LINQ to Entities. Метод OrderBy должен вызываться перед методом Skip.
Я решил это, позволив определить сортировку по умолчанию с помощью частичного метода. Но у меня проблемы с проверкой, действительно ли дерево выражений содержит OrderBy
.
Я сократил проблему до минимума кода:
public partial class Repository
{
partial void ProvideDefaultSorting(ref IQueryable<Category> currentQuery);
public IQueryable<Category> List(int startIndex, int count)
{
IQueryable<Category> query = List();
ProvideDefaultSorting(ref query);
if (!IsSorted(query))
{
query = query.OrderBy(c => c.CategoryID);
}
return query.Skip(startIndex).Take(count);
}
public IQueryable<Category> List(string sortExpression, int startIndex, int count)
{
return List(sortExpression).Skip(startIndex).Take(count);
}
public IQueryable<Category> List(string sortExpression)
{
return AddSortingToTheExpressionTree(List(), sortExpression);
}
public IQueryable<Category> List()
{
NorthwindEntities ent = new NorthwindEntities();
return ent.Categories;
}
private Boolean IsSorted(IQueryable<Category> query)
{
return query is IOrderedQueryable<Category>;
}
}
public partial class Repository
{
partial void ProvideDefaultSorting(ref IQueryable<Category> currentQuery)
{
currentQuery = currentQuery.Where(c => c.CategoryName.Contains(" ")); // no sorting..
}
}
Это не моя реальная реализация!
Но мой вопрос заключается в том, как мне реализовать метод IsSorted
? Проблема в том, что запросы LINQ to Entities всегда имеют тип ObjectQuery
, который реализует IOrderedQueryable
.
Итак, как мне убедиться, что метод OrderBy
присутствует в дереве выражений? Единственный вариант разобрать дерево?
Обновление
Я добавил две другие перегрузки, чтобы прояснить, что речь идет не о том, как добавить поддержку сортировки в репозиторий, а о том, как проверить, действительно ли метод partial ProvideDefaultSorting
добавил OrderBy
в репозиторий. дерево выражений.
Проблема в том, что первый частичный класс генерируется по шаблону, а реализация второй части частичного класса выполняется членом команды в другое время. Вы можете сравнить это с тем, как .NET Entity Framework генерирует EntityContext, он позволяет использовать точки расширения для других разработчиков. Поэтому я хочу попытаться сделать его надежным и не давать сбоев, когда ProvideDefaultSorting
реализован неправильно.
Так что, возможно, вопрос заключается в том, как я могу подтвердить, что ProvideDefaultSorting
действительно добавил сортировку в дерево выражений.
Обновление 2
Ответ на новый вопрос получен и принят, я думаю, мне следует изменить заголовок, чтобы он больше соответствовал вопросу. Или я должен оставить текущее название, потому что оно приведет людей с такой же проблемой к этому решению?