Entity Framework 6 Include missing

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()

>Solution :

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);
    }
}

Leave a Reply