实体框架4和存储库模式

Sam*_*Sam 3 dependency-injection poco repository-pattern entity-framework-4

有人可以解释使用这种模式的好处吗?

我的意思是EF在某种意义上来说不是一个存储库吗?你不能只查询容器并返回那些对象吗?

我看到很多关于POCO,AutoMapper,依赖注入,服务层,IoC的讨论.我只是将一堆东西混合在一起,还是一切都有关系?

谁可以给我解释一下这个?

另外,这些如何与MVC.net,ViewModels和DataModels结合在一起?

谢谢,山姆

RPM*_*984 21

那里有一堆随机问题,所以我会给出一堆随机答案:

  • 存储库(由Martin Fowler定义)定义为"使用类似集合的接口访问域对象,在域和数据映射层之间进行调解"
  • EF是ORM,它是数据映射层
  • 是的,你可以查询EF容器并返回对象,但是消费者"知道太多"关于底层持久性机制,当它不应该知道/关心时 - 因此存储库模式
  • POCO是一种用于从持久性元数据中释放对象的技术(默认使用EF代码).它们还允许您的POCO加倍作为您的域模型.
  • MVC Views使用ViewModels.
  • AutoMapper用于轻松地将ViewModel转换为域模型.
  • 服务层提供控制器和存储库之间的中间层 - 专门用于IQueryable<T>存储库,以将查询具体化为具体序列(例如ICollection<T>).
  • IoC用于解除组件之间的依赖关系,这提供了良好/干净的体系结构和极高的可测试性(您可以通过Mock存储库传递给控制器​​,以单独的方式对它们进行单元测试).

详细说明请求#3

没有存储库的示例控制器:

public class ProductsController
{
   public ActionResult GetProduct(int productId)
   {
       Product p;

       using (var ctx = new MySecretContextWhichIsNowExposed())
       {
          p = ctx.Products.SingleOrDefault(x => x.ProductId == productId);
       }

       return View(p);
   }
}
Run Code Online (Sandbox Code Playgroud)

以上问题:

  1. Controller直接使用实体框架对象上下文,这意味着Web应用程序知道它,并且需要对System.Data.Entity的引用.
  2. 单元测试几乎是不可能的.您将针对实际数据库进行测试,这使其成为集成测试而非单元测试.
  3. Controller具有"如何检索单个产品"的逻辑,当它不应该时 - 这是域/存储库逻辑.

示例Controller with Repository(和IoC):

public class ProductsController
{
   private readonly IProductsRepository _repo;

   public ProductsController(IProductsRepository repo)
   {
      _repo = repo;
   }

   public ActionResult GetProduct(int productId)
   {
       Product p = _repo.FindById(productId);
       return View(p);
   }
}
Run Code Online (Sandbox Code Playgroud)

为什么以上更好:

  1. 控制器不知道EF.不依赖于System.Data.Entity.
  2. Controller不知道Repository的实现,它通过一个接口工作.
  3. Controller不提供有关如何检索产品的逻辑,只提供id.
  4. 2行简单代码.
  5. 测试单位=一块蛋糕.通过MockProductRepositoryctor中的a,然后解决(可以作为内存列表实现).