У меня есть веб-API, где я бы хотел предложить некоторые (ограниченные) запрашиваемые конечные точки для таких вещей, как пейджинг, упорядочение и предварительный выбор результатов (по базе данных: столбцы, включенные в dto). До сих пор все отлично работает, однако у меня много сильно раздутых методов управления с большим количеством технических материалов, и я подумал, есть ли более простой способ для моих требований.Queryable web api
Типичный контроллер выглядит следующим образом:
public HttpResponseMessage GetEntities(int page = MaximumPageIndex,
int pageSize = MinimumPageSize,
string orderBy = null,
[FromUri] EntitySearchCriteria criteria = null)
{
// ensure that page/pageSize lies within possible boundaries
page = page.ToMinimum(MinimumPageIndex);
pageSize = pageSize.ToBounds(MinimumPageSize, MaximumPageSize);
// create any criteria for entity if none is available
criteria = criteria ?? new AnyEntitySearchCriteria();
// create ordering expressions based on string
var orderOptions = orderBy != null
? ExpressionBuilder.CreateSelector<Entity, dynamic>(orderBy)
: ExpressionBuilder.CreateSelector<Entity, dynamic>("Id");
// create paging options
var pagingOptions = new PagingOptions<Entity, dynamic>(page, pageSize, orderOptions);
try {
// get total count from database
var totalCount = _repository.Count();
// get entities by criteria specification (IMemberSpecification<T, TMember>)
var results = _repository.GetEntitiesByCriteria(criteria,
x = new BlablaDto {} // apply result selectors (not shown in example,
// map to paged list
pagingOptions).ToPagedList(page, pageSize, totalCount);
// create "paged" response with paging http headers (rfc 5988)
return Request.CreatePagedResponse(HttpStatusCode.OK, results);
...
}
Это, конечно же, снова и снова, для многих предприятий, которые часто выглядят одинаково. Теперь я знаю, что есть Microsoft OData, но я не могу и не буду использовать его по многим причинам (работает только на IQueryable, странные ответы - например: данные подкачки включены в результат json, а не в заголовки HTTP). поэтому, как я могу сохранить простые контроллеры и сократить повторение кода для этой самой задачи?
Ответ лежит на том, как _repository спроектирован и реализован ... Я не вижу его из кода. –
@Werlang Basic CRUD плюс метод GetEntities(), который принимает ISpecification, IQueryOptions (для сортировки/подкачки, который применяется к базовому IQueryable, возвращаемому поставщиком запроса) и выражение для выбора, чтобы вернуть подмножество полей и/или DTO. – xvdiff
этот репозиторий.GetEntities() может быть перемещен в метод шаблона в базовом контроллере ... тогда ваш Controller.GetEntities() реализует всю эту логику и обрабатывает эту конкретную выборку для каждого типа сущности. –