Шаблон репозитория.NET Общая методология запроса
Я использую шаблон репозитория, у меня есть базовый репозиторий, и я использую Entity Framework и веб-API; мой вопрос - я хочу, чтобы мои клиенты могли запрашивать любые данные динамически; что-то вроде выражений запросов и выборки xml, используемых в Dynamics CRM; Я попробовал шаблон спецификации, но этого недостаточно, поскольку я хочу разрешить клиентскому коду упорядочивать данные с разными столбцами, например, Name asc Address desc, а также разрешить разбиение на страницы для возвращаемого результата, поэтому мои требования к методу
- Общий фильтр, который не зависит от технологии ORM, так как я могу изменить Entity Framework в будущем
- Методология общей сортировки; разрешить множественную сортировку столбцов, например, имя asc адрес desc
- Клиент определяет возвращаемые столбцы или все столбцы, например columnSet, как "Адрес, Имя и Идентификатор" или возвращает всю запись
- Разрешить разбиение на страницы, например, индекс страницы и размер страницы
- Порог поддержки на количество возвращаемых записей, так как большой результат может повлиять на производительность
это мой первоначальный метод, но я не знаю, лучше это или нет
IList<TEntity> AllMatching(ISpecification<TEntity> specification = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
IList<Expression<Func<TEntity, object>>> includes = null,
int? pageIndex = null, int? pageCount = null);
1 ответ
Вы можете начать делать это:
public IQueryable<TEntity> Select(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
IList<Expression<Func<TEntity, object>>> includes = null,
int? page = null,
int? pageSize = null)
{
IQueryable<TEntity> query = _dbSet;
if (includes != null)
{
query = includes.Aggregate(query, (current, include) => current.Include(include));
}
if (orderBy != null)
{
query = orderBy(query);
}
if (filter != null)
{
query = query.AsExpandable().Where(filter);
}
if (page != null && pageSize != null)
{
query = query.Skip((page.Value - 1)*pageSize.Value).Take(pageSize.Value);
}
return query;
}
Как видите, он почти делает все, что вам нужно, поэтому, если вы хотите сделать то же самое в своем Repository
реализации, вы должны использовать пакет nuget LinqKit.
Если вы хотите выбрать определенные столбцы, вы можете создать другой метод, как показано ниже:
IEnumerable<TResult> AllMatching<TResult>(
Expression<Func<TEntity, TResult>> columns,
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
IList<Expression<Func<TEntity, object>>> includes = null,
int? pageIndex = null,
int? pageCount = null)
{
var query=Select(filter,orderby,includes,page,pageSize);
return query.Select(columns);
}