在使用ORM解决方案的ASP.NET MVC中工作时,是否需要使用Repository模式?

Bik*_*Lem 28 asp.net-mvc orm design-patterns domain-driven-design

我有点好奇其他开发人员在使用Entity Framework或NHibernate在ASP.NET MVC中编程时应用Repository模式的经验.在我看来,这种模式已经在ORM中实现了.DbContextDbSet<T>在实体框架和ISessionNHibernate中.这些Repository模式中提到的大部分问题- 如POEEDDD编目- 都是由这些ORM非常充分地实现的.即这些问题是,

  • 坚持
  • OO查看数据
  • 数据访问逻辑抽象
  • 查询访问逻辑

此外,我见过的大多数存储库模式的实现都遵循这种实现模式 - 假设我们正在开发一个博客应用程序.

NHibernate实现:

public class PostRepository : IPostRepository
{
    private ISession _session;

    public PostRepository(ISession session)
    {
        _session = session;
    }

    public void Add(Post post)
    {
        _session.Save(post);
    }

    // other crud methods. 
}
Run Code Online (Sandbox Code Playgroud)

实体框架:

public class PostRepository : IPostRepository
{
    private DbContext _session;

    public PostRepository(DbContext session)
    {
        _session = session;
    }

    public void Add(Post post)
    {
        _session.Posts.Add(post);
        -session.SaveChanges();
    }

    // other crud methods. 
}
Run Code Online (Sandbox Code Playgroud)

在我看来,当我们使用ORM时 - 例如Nhibernate或Entity Framework--创建这些存储库实现是多余的.此外,由于这些模式实现不会超过ORMS中已有的模式实现,因此这些实现更多的是噪声而不是有用的OO抽象.似乎在上述情况下使用存储库模式只不过是开发人员自我扩张和更多的盛大和仪式没有任何可实现的技术利益.你的想法是什么 ??

jga*_*fin 12

如果您不需要能够切换ORM或能够测试任何对ORM /数据库具有依赖性的类,则答案是 否定的.

如果您希望能够切换ORM或能够轻松测试使用数据库层的类:是的,您需要一个存储库(带有接口规范).

如果使用存储库模式,您还可以切换到内存存储库(我在单元测试中执行),XML文件或其他任何内容.

更新

您可以通过Google搜索找到的大多数存储库模式实现的问题是它们在生产中不能很好地工作.他们缺乏限制结果(分页)和排序结果的选项,这是一种惊人的结果.

当存储库模式与UnitOfWork实现相结合并且支持规范模式时,它就会变得光彩夺目.

如果你找到一个拥有所有这些,请告诉我:)(我确实有自己的,一个很好的工作规范部分的例外)

更新2

存储库不仅仅是以抽象的方式访问数据库,例如可以由ORM完成.正常的Repository实现应该处理所有聚合实体(例如OrderOrderLine).在同一个存储库类中处理它们总是可以确保它们是正确构建的.

但是,嘿,你说:这是由ORM自动完成的.嗯,是的,不.如果您创建网站,则很可能只想编辑一个订单行.您是否获取完整订单,循环查找订单,然后将其添加到视图中?

通过这样做,您可以向您的控制器引入不属于那里的逻辑.当网络服务想要同样的事情时你怎么做?复制你的代码?

通过使用ORM,可以很容易地从任何地方获取任何实体myOrm.Fetch<User>(user => user.Id == 1),然后保存它.这可能非常方便,但也会添加代码气味,因为您复制代码并且无法控制对象的创建方式,如果它们具有有效状态或正确关联.

我想到的下一件事是您可能希望能够以集中方式订阅Created,Updated和Deleted等事件.如果你有一个存储库,这很容易.

对我来说,ORM提供了一种将类映射到表的方法,仅此而已.我仍然希望将它们包装在存储库中以控制它们并获得单点修改.

  • @ k3b - 这是一个不好的理由.动态切换ORM很少见.@jgauffin - 我不明白你的更新.如果一个repo是在没有分页或排序的情况下构建的,那么它就没有它.它与模式本身无关. (3认同)
  • @Bikal实际上并没有能够改变ORM的好处,它比那更微妙.您**可以**更改它的事实表明您已成功地将您的域层与数据访问问题分开,为您提供松散耦合,有凝聚力的设计.这意味着域层仅负责对域进行建模.这更容易测试,更容易重构,以及已建立的DDD的所有其他好处. (3认同)