Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 在ASP.NET MVC中使用ORM解决方案时,我们是否需要使用存储库模式?_Asp.net Mvc_Design Patterns_Orm_Domain Driven Design - Fatal编程技术网

Asp.net mvc 在ASP.NET MVC中使用ORM解决方案时,我们是否需要使用存储库模式?

Asp.net mvc 在ASP.NET MVC中使用ORM解决方案时,我们是否需要使用存储库模式?,asp.net-mvc,design-patterns,orm,domain-driven-design,Asp.net Mvc,Design Patterns,Orm,Domain Driven Design,我有点好奇其他开发人员在使用Entity Framework或NHibernate在ASP.NET MVC中编程时应用存储库模式的经验。在我看来,这个模式已经在ORM中实现了DbContext和DbSet在实体框架中,并通过NHibernate中的ISession执行。存储库模式中提到的大多数问题(如和中所述)都由这些ORM充分实现。即这些关注点是, 坚持 面向对象的数据视图 数据访问逻辑抽象 查询访问逻辑 此外,我看到的存储库模式的大多数实现都遵循这个实现模式——假设我们正在开发一个博客应

我有点好奇其他开发人员在使用Entity Framework或NHibernate在ASP.NET MVC中编程时应用存储库模式的经验。在我看来,这个模式已经在ORM中实现了
DbContext
DbSet
在实体框架中,并通过NHibernate中的
ISession
执行。
存储库
模式中提到的大多数问题(如和中所述)都由这些ORM充分实现。即这些关注点是,

  • 坚持
  • 面向对象的数据视图
  • 数据访问逻辑抽象
  • 查询访问逻辑
此外,我看到的存储库模式的大多数实现都遵循这个实现模式——假设我们正在开发一个博客应用程序

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. 
}
实体框架:

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. 
}

在我看来,当我们使用ORM(如Nhibernate或EntityFramework)时,创建这些存储库实现是多余的。此外,由于这些模式实现所做的并不比ORMS中已有的多,因此它们更像是噪声,而不是有用的OO抽象。在上述情况下使用存储库模式似乎只不过是开发人员的自我强化和更多的炫耀和仪式,没有任何可实现的技术好处。您的想法是什么?

如果您不需要切换ORM或测试任何依赖于ORM/数据库的类,那么答案是

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

您还可以切换到内存存储库(我在单元测试中就是这么做的)、XML文件或任何使用存储库模式的东西

更新

通过谷歌搜索可以发现,大多数存储库模式实现的问题是,它们在生产环境中工作得不太好。他们缺乏限制结果(分页)和排序结果的选项,这有点令人惊讶

当存储库模式与UnitOfWork实现相结合并支持规范模式时,它就大放异彩了

如果您发现其中一个拥有所有这些,请告诉我:)(我有自己的,一个运行良好的规范部分的例外)

更新2

存储库不仅仅是以一种抽象的方式访问数据库,就像ORM可以完成的那样。正常的存储库实现应该处理所有聚合实体(例如
Order
OrderLine
)。在同一个存储库类中处理它们时,您可以始终确保正确构建了它们

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

通过这样做,您向控制器引入了不属于那里的逻辑。当一个Web服务需要相同的东西时,你怎么做?复制你的代码

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

接下来想到的是,您可能希望能够以集中的方式订阅创建、更新和删除等事件。如果您有一个存储库,那么这很容易


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

我认为只有当您希望降低依赖级别时才有意义。抽象地说,您可以在基础设施包中包含IPostRepository,并在EF或NH或其他基础上构建此接口的几个独立实现。这对TDD很有用

实际上,NH会话(和EF上下文)实现了类似于“工作单元”模式的东西。此外,使用NH和存储库模式,您可能会遇到许多错误和架构问题


例如,NH实体可以绕过存储库实现进行保存。您可以从会话(Repository.Load)获取它,更改它的一个属性,然后调用session.Flush(例如,在请求结束时,因为存储库模式不假设刷新),您的更改将在数据库中成功处理。

您只提到了基本的CRUD操作。直接执行这些操作确实意味着您必须了解事务、刷新和存储库可以完成的其他事情,但我想当您考虑复杂的检索查询时,存储库的价值会变得更加明显

假设您决定直接在应用程序层中使用NHibernate会话

您将需要使用HQL或NHibernate标准执行与WHERE子句和ORDER BY等等效的操作。这意味着您的代码必须引用NHibernate,并且包含特定于NHibernate的想法。这使得您的应用程序很难测试,其他不熟悉NH的人也很难遵循。对repository.GetCompletedOrders的调用比包含“where IsComplete=true和IsDeleted=false…”等内容的调用更具描述性和可重用性

您可以使用Linq来代替NHibernate,但是现在您很容易忘记您正在使用IQueryable。你可能会把Linq表达式链接到哪个基因上