【问题标题】:MVC3 best practices to save view with multiple entities使用多个实体保存视图的 MVC3 最佳实践
【发布时间】:2012-04-25 23:16:00
【问题描述】:

给定一个使用 ViewModel 模式和带有实体框架的 Repository 模式的 MVC3 应用程序。

如果我有一个由多个实体组成的创建和更新视图,那么保存数据的最佳做法是什么?

我应该使用抽象服务层保存日期,该服务层将每个实体的数据保存在其各自的存储库中,还是应该使用存储过程将数据保存在存储库中?

我愿意接受任何建议或建议。

提前致谢!

【问题讨论】:

  • 这真的取决于实体之间的关系。一个实体的价值是否依赖于另一个?这些实体真的只是一个大实体,被分成更小的可管理位吗?
  • @Garvin 它实际上只是一个带有急切加载相关实体的大实体。例如,我会急切地加载小部件的详细信息,然后必须编辑其中一个详细信息。由于我的上下文在我检索数据后被释放,我相信我必须附加每个相关实体然后保存。我必须在主对象的存储库的 Save 方法中执行此操作,因此保存所有相关对象有点误导。想法?

标签: asp.net-mvc-3 entity-framework repository-pattern view-model-pattern


【解决方案1】:

这是 DDD/CQRS 方法最有意义的情况之一。简而言之,您有一些对特定行为(聚合)进行建模的业务对象。 chrage 中有一个对象称为聚合根 (AR),它具有明确的边界。当你想保存它时,你将整个 AR 发送到存储库,然后将所有内容保存为事务。

工作流程

用户通过视图模型发送数据。然后控制器将从存储库中检索 AR,如果它是新的,则创建。输入数据通常通过 AR 方法映射到 AR。如果 AR 发现数据或其结果违反了某些业务规则,那么它应该抛出异常(我们假设 asp.net mvc 已经自动执行了基本验证)。

如果一切正常,控制器会将 AR 发送到 repo,然后它将继续将 AR 映射到 EF 实体,然后将其保存,这一切都在一个事务中。

简而言之,这就是我的做法。当然,我实际上会实现它有点不同,但概念是相同的。重要的部分是将所有数据发送到知道如何处理关系的 AR。

要点

请注意,我只是在 AR 进入 repo 之后才提到 EF。这意味着,AR 与 EF 实体无关,完全分离并服务于实际的业务模型。仅在模型更新后,我们才关心 EF 并且仅在 repo 内(因为 EF 是 repo 的实现细节)。存储库仅将 AR 数据传输(基本上映射)到相关的 EF 实体,然后保存实体。

在业务(域)模型和持久性模型(EF 实体)之间有一个非常清晰的区别很重要。不要使用 EF 处理业务规则,仅使用它来查看/检索数据库中的数据。 EF 仅用于抽象 RDBMS 访问,将其用作虚拟 OOP 数据库。

您提到了 ViewModel 模式。我还没有听说过这样的模式,每次您使用 MVC 时,您已经在使用 ViewModels。再一次,诀窍是不要将 EF 实体用作 ViewModel。使用适合视图的“哑”视图模型。通过专门的查询存储库填充 VM,该存储库将直接返回 VM 部件。存储库将查询 EF 实体,然后返回那些简单 DTO 的 VM 位。那是因为显示数据时不需要验证和业务规则。

我认为保持层,尤其是每个层的模型分开是一个很好的做法。对于更新的东西,使用复杂的业务对象(域模型)来完成艰苦的工作,然后只将它们的状态转移到 EF(通过存储库)。要阅读内容,请查询 EF 并返回适合 VM 的简单 DTO。

这正是 CQRS 的真正意义所在:不要试图在单个模型中适应不同的职责(写入和读取)。

【讨论】:

  • 这有点像我的想法,区别在于在抽象服务层中解析 A​​R 以避免在控制器或存储库中这样做;实施差异主要与您的建议有关。那么....将 AR 传递给存储过程,以便从控制器插入和更新到 repo 会更干净吗?
  • 您不解析 AR。您通过命令(来自控制器或服务)将输入数据映射到 AR,然后将 AR 发送到存储库并在存储库内部,将 AR 映射到 EF 实体。 sproc与否无关紧要。重要的是保持层分开。这就是你保持它们清洁的方式。
  • 对。这就是我所说的解析。感谢您的帖子!
猜你喜欢
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
  • 2011-10-26
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 2014-02-20
相关资源
最近更新 更多