Home > Enterprise >  Creating a group by parameter for the get method in a generic repository for entity framework
Creating a group by parameter for the get method in a generic repository for entity framework

Time:10-01

I am using the repository pattern with Entity Framework as described in this article: repository pattern with Entity Framework In the part where the GenericRepository is described (Generic Repository) there is a method which is used to get entities from the database set called Get. It has an orderBy but no groupBy. I am wondering how one might implement a groupBy in the same manner as the orderBy so that you can specify which field to group by dynamically on the entity.

What I have come up with is this:

Func<IQueryable<TEntity>, IGrouping<string, TEntity>> groupBy = null

and then in the method code it should be used something like this:

if(groupBy != null)
{
    query = groupBy(query).ToList();
}

But this is not compiling since the IGrouping is not queryable. Does someone know how to point me in the right direction or has a solution to this?

Edit: The reason for doing this instead of using groupby on the returned list is for performance reasons. I want the groupby to be sent as an sql statement to the database and resolved there.

CodePudding user response:

Grouping has no sense without projection. So you have to define new method which returns IEnumerable with new type.

I have added sample of such method. Also removed includeProperties because EF Core ignores Includes during grouping.

Usage sample:

_orderRepostory
   .GetGrouped(e => e.UserId, g => new { UserId = g.Key, Count = g.Count()});

And implementation:

 public class GenericRepository<TEntity> where TEntity : class
 {
    ... // other code

    public virtual IEnumerable<TResult> GetGrouped<TKey, TResult>(
        Expression<Func<TEntity, TKey>> groupingKey,
        Expression<Func<IGrouping<TKey, TEntity>, TResult>> resultSelector,
        Expression<Func<TEntity, bool>>? filter = null)
    {
        var query = dbSet.AsQueryable();

        if (filter != null)
        {
            query = query.Where(filter);
        }

        return query.GroupBy(groupingKey).Select(resultSelector);
    }
 }
  • Related