给定一个使用 ViewModel 模式和带有实体框架的存储库模式的 MVC3 应用。
如果我有一个由多个实体组成的创建和更新视图,保存数据的最佳做法是什么?
我应该使用抽象的服务层来保存日期,该服务层将保存每个实体的数据及其各自的存储库,还是应该使用存储过程将数据保存在存储库中?
我愿意接受任何建议或建议。
提前感谢!
这是 DDD/CQRS 方法最有意义的情况之一。简单地说,您有一些业务对象对特定行为(聚合)进行建模。chrage 中有一个对象称为聚合根 (AR),它具有明确的边界。当您想要保存它时,您将整个 AR 发送到存储库,然后将所有内容保存为事务。
工作流程
用户通过视图模型发送数据。然后,控制器将从存储库中检索 AR,或者如果它是新的 .输入数据通常通过 AR 方法映射到 AR。如果AR发现数据或其结果违反了某些业务规则,那么它应该抛出异常(我们假设基本验证已经由 asp.net mvc自动执行)。
如果一切正常,控制器会将 AR 发送到存储库,然后它将继续将 AR 映射到 EF 实体,然后将其保存,所有这些都在事务中完成。
简而言之,我会怎么做。当然,我实际上会实现它有点不同,但概念是相同的。重要的部分是将所有数据发送到AR,AR将知道如何处理关系。
要点
请注意,我只是在 AR 进入存储库之后才提到 EF。这意味着,AR与EF实体无关是完全分离的,服务于实际的商业模式。只有在更新模型后,我们才关心 EF 并且仅在存储库中(因为 EF 是存储库的实现详细信息)。存储库仅将 AR 数据传输(基本上映射)到相关的 EF 实体,然后保存实体。
在业务(域)模型和持久性模式(EF 实体)之间有一个非常明确的区别非常重要。不要使用 EF 来处理业务规则,仅使用它来盯视/检索数据库中的数据。EF 仅用于抽象 RDBMS 访问,将其用作虚拟 OOP 数据库。
您提到了视图模型模式。我还没有听说过这样的模式,每次你使用 MVC 时,你就已经在使用 ViewModels。再说一次,诀窍是不要将 EF 实体用作视图模型。使用适合视图的"哑"视图模型。通过专用的查询存储库填充 VM,该存储库将直接返回 VM 部件。存储库将查询 EF 实体,然后返回那些简单 DTO 的 VM 位。这是因为在显示数据时不需要验证和业务规则。
我认为保持层,尤其是每层的模型分开是一个很好的做法。要更新内容,请使用复杂的业务对象(域模型),这将完成艰苦的工作,然后仅将其状态传输到 EF(通过存储库)。若要读取内容,请查询 EF 并返回适合 VM 的简单 DTO。
这就是 CQRS 的真正意义所在:不要试图在单个模型中适应不同的职责(写入和读取)。