创建读取模型(聚合)的最佳方法

时间:2012-09-18 14:34:13

标签: c# .net asp.net-mvc domain-driven-design

我必须用CartLine和其他一些信息创建一个复杂的“阅读模型”(购物车)。目前我有一个基于许多其他对象(Cart,Operation ...)的ViewModel,构建此对象的逻辑在Respository和Controller(不在Aggregate中)中调度,我想重构这个代码,存储库直接返回“读取模型”(格式化文本,价格......)。

我只允许使用Dapper的存储过程(客户端策略)。我正在寻找一种更好的方法来创建这个阅读模型:

1.调用现有存储过程,在DTO上映射存储的proc结果,然后在我的读模型上再次映射结果

public class Cart
{
    public Cart(CartDb cartDb, IEnumerable<CartDetailDb> cartDetailsDb, 
                                                      OperationDB operationDb)
    {
        //Code
    }
}

- &GT;有两个级别的对象,我认为这是一团糟

2.创建将直接映射到我的阅读模型的存储过程(以避免DTO)

- &GT;我不喜欢这种方法,因为我最终可能会在存储过程中添加一些逻辑

3.使用ViewModel

其他建议?

1 个答案:

答案 0 :(得分:1)

如果我理解正确,则此实体的数据模型与此Read实体的域模型不完全一致。您还希望您的存储库层直接返回{strong>域模型版本的Read,而无需中间DTO层。

在我看来,选项#1 最有意义。由于数据模型和域模型之间存在阻抗不匹配,因此需要在某处使用映射逻辑来在两个模型之间转换数据。这个逻辑的最合适的位置将在你的存储库层内,因为这个层的整个目的是在域和它们的持久性之间映射对象。

这并不意味着您需要创建一个DTO图层来映射您刚刚转过来并重新映射到域对象的存储过程。您可以直接在数据访问层返回的结果集上执行转换逻辑,并在一个步骤中将其转换为域对象。

在数据访问的情况下,对DTO的需求在很大程度上取决于您用于数据访问的技术。例如,如果您使用的是ADO.net库(SqlCommandSqlConnection等),那么可能不需要DTO。但是,如果您正在使用像Entity Framework或NHibernate这样的ORM,那么将这些工具生成的对象严格地用作DTO并映射到完整的成熟域对象可能是有意义的。当然,由于这些对象是为您生成的,因此几乎消除了使用DTO层时的任何维护问题。

这并不意味着您需要将转换逻辑放在存储过程中,以使数据层返回与您的域模型完全匹配的结果集。我会不惜一切代价避免这种情况正如你自己所说,这会将域逻辑放入你的数据库中。

最后,您提到域对象包含“格式化文本”,例如price。我想指出,大多数情况下,文本格式化实际上是UI层的一部分,而不是您的域模型。这意味着,如果您的模型上有属性,例如Price,则应将其表示为DoubleDecimal,而不是String格式为货币。换句话说,该值应 5.00 而不是“$ 5.00”

为了处理这些格式化翻译,使用您提到的ViewModel包装您的域对象是合适的,以处理从域到UI层的转换。在这些情况下使用严格的分离问题有助于创建一个更易于维护的更健壮的系统。