Click here to Skip to main content
15,920,468 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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?


What I have tried:

I saw PaginatedList but I don't want to use it and want to stick with the Generic my repository.

I thought of Domain class but cannot find out how will I manage with Automapper for TotalCount and other fileds mapping.
Posted
Updated 1-Jun-20 23:47pm

1 solution

I'm not sure about "best practises" - there are many different ways to achieve the same thing, with varying degrees of complexity.

What I tend to do is return a class which encapsulates the results:
C#
public class EntityList<TEntity>
{
    public int TotalCount { get; set; }
    public int FilteredCount { get; set; }
    public IReadOnlyList<TEntity> PageData { get; set; }
}
C#
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,
    };
}
Alternatively, OData allows you to request the total number of records to be returned in the response:
Query options overview - OData | Microsoft Docs[^]

And GraphQL takes a slightly different approach:
Pagination | GraphQL[^]
 
Share this answer
 
Comments
Maciej Los 2-Jun-20 6:01am    
5ed!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900