Reputation: 65
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
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
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