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