sam_roy Ответов: 1

Универсальный репозиторий с подкачкой для метода getall для включения количества элементов


I am using a generic repository something like EFRepo<TEntity> which has a method


<pre>public IEmerable<TEntity> GetAll(
 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)
 {
        var query = context.Set<TEntity>().AsQueryable();

        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.ToList();
 }



The problem lies here I am trying to DDD so 'TEntity' is actually entity class for EF. I need to return the total records count of the total database record as well. How shall I do it following best practises for an API?


Что я уже пробовал:

Я видел PaginatedList, но я не хочу его использовать и хочу придерживаться универсального моего репозитория.

Я думал о классе домена, но не могу понять, как я буду управлять с помощью Automapper для сопоставления TotalCount и других файлов.

1 Ответов

Рейтинг:
0

Richard Deeming

Я не уверен насчет "лучших практик" - есть много разных способов достичь одного и того же, с разной степенью сложности.

То, что я обычно делаю, - это возвращаю класс, который инкапсулирует результаты:

public class EntityList<TEntity>
{
    public int TotalCount { get; set; }
    public int FilteredCount { get; set; }
    public IReadOnlyList<TEntity> PageData { get; set; }
}
public EntityList<TEntity> GetAll(
    Expression<Func<TEntity, bool>> filter = null,
    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
    IEnumerable<Expression<Func<TEntity, object>>> includes = null,
    int? page = null, int? pageSize = null)
{
    var query = context.Set<TEntity>().AsQueryable();
    if (includes != null)
    {
        query = includes.Aggregate(query, (current, include) => current.Include(include));
    }
    
    int totalCount = query.Count();
    int filteredCount = totalCount;
    
    if (filter != null)
    {
        query = query.AsExpandable().Where(filter);
        filteredCount = query.Count();
    }
    
    if (orderBy != null)
    {
        query = orderBy(query);
    }
    if (page != null && pageSize != null)
    {
        query = query.Skip((page.Value - 1) * pageSize.Value).Take(pageSize.Value);
    }
    
    var pageData = query.ToList();
    
    return new EntityList<TEntity>
    {
        TotalCount = totalCount,
        FilteredCount = filteredCount,
        PageData = pageData,
    };
}
Кроме того, OData позволяет запросить общее количество записей, которые будут возвращены в ответе:
Обзор параметров запроса - OData | Microsoft Docs[^]

А GraphQL использует несколько иной подход:
Разбиение На Страницы | GraphQL[^]


Maciej Los

5ed!