Abdurahman Almatrodi
Abdurahman Almatrodi

Reputation: 65

Add Include to repository

I have a working repository.

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
    protected readonly DbContext Context;

    public Repository(DbContext context)
    {
        Context = context;
    }

    public TEntity Get(int id)
    {
        return Context.Set<TEntity>().Find(id);
    }

    public IEnumerable<TEntity> GetAll()
    {
        return Context.Set<TEntity>().ToList();
    }

    public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
    {
        return Context.Set<TEntity>().Where(predicate);
    }

    public TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate)
    {
        return Context.Set<TEntity>().SingleOrDefault(predicate);
    }

    public void Add(TEntity entity)
    {
        Context.Set<TEntity>().Add(entity);
    }

    public void Remove(TEntity entity)
    {
        Context.Set<TEntity>().Remove(entity);
    }
}

As I read in coding repositories, that you don't add any class until you really need it. Now, I need to add Include. I found this one in this community Use Include() method in repository:

public static class IncludeExtension
{
    public static IQueryable<TEntity> Include<TEntity>(this IDbSet<TEntity> dbSet,
                                                   params Expression<Func<TEntity, object>>[] includes)
                                                   where TEntity : class
    {
        IQueryable<TEntity> query = null;
        foreach (var include in includes)
        {
            query = dbSet.Include(include);
        }

        return query ?? dbSet;
    }
}

Then, I changed it to fit in my code (As I think) to be:

public IEnumerable<TEntity> Include(IDbSet<TEntity> dbSet,
                                    params Expression<Func<TEntity, object>>[] includes)
{
    IEnumerable<TEntity> query = null;
    foreach (var include in includes)
    {
        query = dbSet.Include(include);
    }

    return query ?? dbSet;
}

With direct access to context, I am able to write:

Provinces = _cmsDbContext.Provinces.Include(c => c.District).Include(c => c.District.Country).ToList();

But, with repository, I can't write:

Provinces = Currentunitofwork.ProvinceRepository.Include(c => c.District).Include(c => c.District.Country).ToList();

I got error:

cannot convert lambda expression to type IDbSet<Province> because it is not a delegate type

What is the problem here, please.

Upvotes: 0

Views: 6868

Answers (2)

Adam Carr
Adam Carr

Reputation: 688

I suspect that your code is passing in the lambda expression to the IDbSet parameter and can not convert it to that type.

I have not been able to test but it compiles, if the method is a member of the Repository class then try this.

public IEnumerable<TEntity> Include(params Expression<Func<TEntity, object>>[] includes)
{
    IDbSet<TEntity> dbSet = Context.Set<TEntity>();

    IEnumerable<TEntity> query = null;
    foreach (var include in includes)
    {
        query = dbSet.Include(include);
    }

    return query ?? dbSet;
}

Upvotes: 3

Abdurahman Almatrodi
Abdurahman Almatrodi

Reputation: 65

Again thanks to @Adam Carr.

This is the method code now:

public IQueryable<TEntity> Include(params Expression<Func<TEntity, object>>[] includeExpressions)
{
    IDbSet<TEntity> dbSet = Context.Set<TEntity>();

    IQueryable<TEntity> query = null;
    foreach (var includeExpression in includeExpressions)
    {
        query = dbSet.Include(includeExpression);
    }

    return query ?? dbSet;
}

What I change is use Set as a method not a property. So, instead of:

IDbSet<TEntity> dbSet = Context.Set<TEntity>;

I used:

IDbSet<TEntity> dbSet = Context.Set<TEntity>();

Also, I used IQueryable instead of IEnumerable.

Upvotes: 0

Related Questions