MVC 5 EF6工作单元和存储库模式

时间:2016-06-02 11:01:08

标签: c# asp.net-mvc entity-framework repository-pattern unit-of-work

如何在MVC 5和EF6中实现工作单元和存储库模式?以前我通过使用注入我的控制器的单个存储库来避免对工作单元的任何需求,如下所示:

public class ProductController : BaseController
{
    private IShopRepository _repository;


    public ClassController()
        : this(new ShopRepository())
    {
    }

    public ClassController(IShopRepository repository)
    {
        _repository = repository;
    }


    ....

}

但是现在我想重构代码,以便我为每个实体类型都有一个单独的存储库,例如。 ProductRepository,CustomerRepository等,能够将多个存储库注入控制器,同时确保使用相同的dbcontext。

阅读http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web-application上的微软教程,架构师现在建议不再需要存储库和工作单元模式,但他们没有提供如何在他们的示例中实现或构建存储库的任何示例?

有些人甚至开始将存储库重命名为服务?

如何使用EF6构建您的存储库并在MVC5中实现工作单元,也许使用Unity等IOC?或者另一种解决方案是什么?

我按照以下方针工作,但不确定这是否是最佳解决方案,如何添加工作单元?

public class ShopContext : DbContext
{
    public ShopContext() : base("name=ShopContext")
    {
    }

    public DbSet<Product> Products { get; set; }
    public DbSet<Customer> Customers { get; set; }
    ...

}


public interface IProductRepository
{
   IEnumerable<Product> GetAll();
   ...
}


public interface ICustomerRepository
{
   IEnumerable<Customer> GetAll();
   ...
}

public class ProductRepository : IDisposable, IProductRepository
{
     private ShopContext _context;

     public ProductRepository()
     {
    _context  = new ShopContext();

     }

     public IEnumerable<Product> GetAll()
     {
        return _context.Products;
     }

     // Other methods not displayed

     protected void Dispose(bool disposing)
     {
       if (disposing)
       {
           if (_context != null)
           {
              _context.Dispose();
              _context = null;
           }
       }
     }

     public void Dispose()
     {
       Dispose(true);
       GC.SuppressFinalize(this);
     }

}

public class CustomerRepository : IDisposable, ICustomerRepository
{
     private ShopContext _context;

     public CustomerRepository()
     {
        _context  = new ShopContext();

     }

     public IEnumerable<Customer> GetAll()
     {
        return _context.Customers;
     }

     // Other methods not displayed

     protected void Dispose(bool disposing)
     {
       if (disposing)
       {
           if (_context != null)
           {
              _context.Dispose();
              _context = null;
           }
       }
     }

     public void Dispose()
     {
       Dispose(true);
       GC.SuppressFinalize(this);
     }
}


public class ProductsController : BaseController
{

   private IProductRepository _productRepository;
   private ICustomerRepository _customerRepository;


   public ProductsController()
        : this(new ProductRepository(), new CustomerRepository())
    {
    }

   public ProductsController(IProductRepository productRepository, ICustomerRepository customerRepository)  
   {
       _productRepository = productRepository;
       _customerRepository = customerRepository;

   }

   // Other controller methods not shown.
} 

示例代码会有所帮助。

2 个答案:

答案 0 :(得分:3)

可以找到最好的工作示例是米塔尔先生在codeproject的系列节目 他正在使用Entity FrameworkGeneric Repository patternUnit of Work。 跟上他,你会知道这一切是如何运作的 这是链接Mittal Series

答案 1 :(得分:0)

正如@Thomas已经在评论中说明的那样,我认为你在这里所说的是服务层而不是存储库。这两个术语经常互换使用,但它们不是一回事。

存储库模式旨在提供数据库的抽象,以便数据库可以在不影响其余代码的情况下进行更改。 EF6中的DBContext已经为您做了,例如,一个名为one thing的表,但映射到具有不同名称的类。 DBContext也已经实现了工作单元模式,因为它将在单个事务中执行所有操作,直到您在上下文中调用SaveChanges / SaveChangesAsync为止。

然后,服务层为用户界面层提供方法。它从存储库调用方法来执行此操作。

使用简单的模型,服务层和存储库看起来是相同的,但是您的存储库通常会映射到一个业务对象(例如,联系人),因为您的服务层可能会封装许多对象(例如,客户业务实体,在保存时将数据存储到Contact和CustomerProfile存储库中),使用工作单元确保提交或回滚两个更改。

这个excellent existing stack overflow answer by @ken2k更详细地介绍了这一点。