I have a project broken into separate classes for an MVC project using Entity Framework 6. One class has a Generic Interface and then it is inherited
public interface IRepository<T> where T : class
{
IEnumerable<T> GetAll();
}
Inherited as below
public class Repository<T> : IRepository<T> where T : class
{
protected readonly DbContext _context = null;
private readonly DbSet<T> _entities;
public GenericRepository(DbContext context)
{
_context = context;
_entities = _context.Set<T>();
}
public IEnumerable<T> GetAll()
{
return _entities;
}
}
This works fine and i then use this in a customer class as below
public class CustomerRepository : Repository<Customer>, ICustomerRepository
{
public CustomerRepository(DataContext context) : base(context)
{
}
public List<Customer> GetPremiumCustomers()
{
return GetAll().Where(p => p.Premium).ToList();
}
}
So far so good and everything returns as expected.
I need to Include a couple of additional tables that are linked to the customers.
When i go to the Repository
class and against _entities
i press the . key i see Include
in the menu.
I then go into the CustomerRepository
and do the same with GetAll().
and along other methods along that line but Include
isnt shown?
I tried adding using System.Data.Entity
to the top of the Customer
class but that didnt bring the option either but it is available in the top most class? What am i missing here?
I was trying to achieve something along the lines of
GetAll().Include("Address").Where(p => p.Premium).ToList()
CodePudding user response:
In Entity Framework 6, the Include
method is defined on the DbQuery<T>
class (DbSet<T>
is derived from DbQuery<T>
). Your GetAll
method on the other hand returns an IEnumerable<T>
. The compiler does not know that you return a DbSet<T>
in the form of the IEnumerable<T>
, hence the method is not offered.
If you want to offer the caller of GetAll
to use the Include
method, you can change the return type, e.g.:
public interface IRepository<T> where T : class
{
DbQuery<T> GetAll();
}
Please note by using DbQuery<T>
as your return type, the interface shows that you are using Entity Framework and you do not hide this detail from the user of the interface. In order to hide this, you can offer another method that accepts a parameter for the include and still returns an IEnumerable<T>
:
public interface IRepository<T> where T : class
{
IEnumerable<T> GetAll();
IEnumerable<T> GetAllWithInclude(string include);
}
public class Repository<T> : IRepository<T> where T : class
{
protected readonly DbContext _context = null;
private readonly DbSet<T> _entities;
public GenericRepository(DbContext context)
{
_context = context;
_entities = _context.Set<T>();
}
public IEnumerable<T> GetAll()
{
return _entities;
}
public IEnumerable<T> GetAllWithInclude(string include)
{
return _entities.Include(include);
}
}