Why Avoid Using Repository Pattern with Entity Framework?

asp.net-mvcentity-frameworkunit-of-work

During a job interview, I was asked to explain why the repository pattern isn't a good pattern to work with ORMs like Entity Framework. Why is this the case?

Best Answer

I don't see any reason for the Repository pattern to not work with Entity Framework. Repository pattern is an abstraction layer you put on your data access layer. Your data access layer can be anything from pure ADO.NET stored procedures to Entity Framework or an XML file.

In large systems, where you have data coming from different sources (database/XML/web service), it is good to have an abstraction layer. The Repository pattern works well in this scenario. I do not believe that Entity Framework is enough abstraction to hide what goes on behind the scenes.

I have used the Repository pattern with Entity Framework as my data access layer method and am yet to face a problem.

Another advantage of abstracting the DbContext with a Repository is unit-testability. You can have your IRepository interface to which has 2 implementations, one (the real Repository) which uses DbContext to talk to the database and the second, FakeRepository which can return in-memory objects/mocked data. This makes your IRepository unit-testable, thus other parts of code which uses IRepository.

public interface IRepository
{
  IEnumerable<CustomerDto> GetCustomers();
}
public EFRepository : IRepository
{
  private YourDbContext db;
  private EFRepository()
  {
    db = new YourDbContext();
  }
  public IEnumerable<CustomerDto> GetCustomers()
  {
    return db.Customers.Select(f=>new CustomerDto { Id=f.Id, Name =f.Name}).ToList();
  }
}
public MockRepository : IRepository
{
  public IEnumerable<CustomerDto> GetCustomers()
  {
    // to do : return a mock list of Customers
    // Or you may even use a mocking framework like Moq
  }
}

Now using DI, you get the implementation

public class SomeService
{
  IRepository repo;
  public SomeService(IRepository repo)
  {
     this.repo = repo;
  }  
  public void SomeMethod()
  {
    //use this.repo as needed
  }    
}