IRepository and Unit Of Work vs Eager Loading

c# eager-loading entity-framework-6

Accepted Answer

A helper class containing your include definitions may be created:

abstract class IncludeDefinition<TEntity>
{
    public abstract IQueryable<TEntity> Include(IQueryable<TEntity> entities);
}

class IncludeDefinition<TEntity, TProperty> : IncludeDefinition<TEntity>
{
    public IncludeDefinition(Expression<Func<TEntity, TProperty>> includeEx)
    {
        _includeEx = includeEx;
    }

    private readonly Expression<Func<TEntity, TProperty>> _includeEx;

    public override IQueryable<TEntity> Include(IQueryable<TEntity> entities)
    {
        return entities.Include(_includeEx);
    }
}

use the thenIncludeDefinition in theGet method

public IEnumerable<Muscle> Get(params IncludeDefinition<Muscle>[] includes)
{
    IQueryable<Muscle> muscles = ...;
    foreach (var item in includes)
    {
        muscles = item.Include(muscles);
    }
    return muscles.ToList();
}

then invoke the method.

_unitOfWork.MuscleRepository
    .Get(new IncludeDefinition<Muscle, MuscleType>(m => m.MuscleType));

// Include as many as you wish
_unitOfWork.MuscleRepository
    .Get(new IncludeDefinition<Muscle, MuscleType>(m => m.MuscleType),
         new IncludeDefinition<Muscle, SomeOtherRelatedEntity>(m => m.SomeOtherProperty));

Instead of writing complex syntax, Edit here comes some way to just include.

design a new user interfaceIQueryRepository that encouragesGet without being specific, containsInclude , deduceIGenericRepository while using this interface:

public interface IQueryRepository<TEntity>
     where TEntity : class
{
    IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null);

    IQueryRepository<TEntity> Include<TProperty>(Expression<Func<TEntity, TProperty>> referenceExpression);
}

public interface IGenericRepository<TEntity> : IQueryRepository<TEntity>
     where TEntity : class
{
    IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        params IncludeDefinition<TEntity>[] include);

    // other methods like GetByID, Add, Update...
}

Refresh theGenericRepository Definition: It employs the strategy withIncludeDefinition that I originally outlined, and it provides aGenericQueryRepositoryHelper when Include is known as.

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    internal DbSet<TEntity> dbSet;


    public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null)
    {
        return Get(filter, orderBy, new IncludeDefinition<TEntity>[0]);
    }

    public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, params IncludeDefinition<TEntity>[] includes)
    {
        IQueryable<TEntity> query = dbSet;

        foreach (var item in includes)
        {
            query = item.Include(query);
        }

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

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }

    public IQueryRepository<TEntity> Include<TProperty>(Expression<Func<TEntity, TProperty>> referenceExpression)
    {
        return new GenericQueryRepositoryHelper<TEntity>(this, new IncludeDefinition<TEntity, TProperty>(referenceExpression));
    }

    // other methods like GetByID, Add, Update...
}

Execute theGenericQueryRepositoryHelper to keep things in one place and use them whenGet is known as

public class GenericQueryRepositoryHelper<TEntity> : IQueryRepository<TEntity>
    where TEntity : class
{
    private readonly IList<IncludeDefinition<TEntity>> _includeDefinitions;
    private readonly IGenericRepository<TEntity> _repository;

    internal GenericQueryRepositoryHelper(IGenericRepository<TEntity> repository, IncludeDefinition<TEntity> includeDefinition)
    {
        _repository = repository;
        _includeDefinitions = new List<IncludeDefinition<TEntity>> { includeDefinition };
    }

    public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null)
    {
        return _repository.Get(filter, orderBy, _includeDefinitions.ToArray());
    }

    public IQueryRepository<TEntity> Include<TProperty>(Expression<Func<TEntity, TProperty>> referenceExpression)
    {
        _includeDefinitions.Add(new IncludeDefinition<TEntity, TProperty>(referenceExpression));
        return this;
    }
}

Happy searching, included

var repo = new GenericRepository<Muscle>(...);
repo.Include(x => x.MuscleType)
    .Include(x => x.MuscleType.Muscles)
    .Get(x => x.MuscleName == "Test", x => x.OrderBy(m => m.MuscleName));
4
10/23/2018 6:00:49 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow