【问题标题】:What is the proper way of using DTOs in this case?在这种情况下使用 DTO 的正确方法是什么?
【发布时间】:2011-03-26 20:25:52
【问题描述】:

我有以下域类:

public class Product
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Product> RelatedProducts { get; set; }
}

我有以下 DTO 类:

public class ProductDTO
{
    public ProductDTO(Product product)
    {
        Id = product.Id;
        Name = product.Name;
    }

    public Guid Id { get; private set; }
    public string Name { get; private set; }
}

我的服务中有以下方法:

public ProductDTO GetBySlug(string slug)
{
    Product product = productRepository.GetBySlug(slug);
    return (product != null) ? new ProductDTO(product) : null;
}

我的控制器中有以下操作:

public ActionResult Details(string slug)
{
    ProductDTO viewModel = productService.GetBySlug(slug);
    return View("Details", viewModel);
}

阅读了一下之后,我的理解是使用 DTO 作为视图模型是可以的,因为当前的场景很简单直接。当我想要返回的数据变得有点复杂时,我就会感到困惑。假设我也想将相关产品列表返回到视图中。我应该在哪里添加这个列表?

我了解到 DTO 是用于传输数据的域实体的扁平化版本。这是否意味着在 DTO 中不应允许包含相关产品的通用列表?到目前为止,我收到的答案表明了这一点。那么如何将相关产品送到控制器?

一个选项是:

我不会在服务中返回 ProductDTO,而是创建一个新类,其中包含 ProductDTO 和相关产品的 ProductDTO 类型列表,然后从服务中返回它。然后在控制器中,我要么将新类传递给视图,要么创建一个单独的 ProductViewModel 来保存 ProductDTO 和相关产品的 ProductDTO 类型的列表,填充它并将其传递给视图。

这是个好主意还是坏主意?为什么?

谢谢

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-2 domain-driven-design dto


    【解决方案1】:

    我根本不会将列表放在 DTO 中,因为它自然不属于那里。而且我也不确定“包装类”是什么意思。您只需要一个产品列表,在服务上使用另一个方法返回此列表是完全可以的。

    因此,您的服务中会出现这样的情况:

    public IList<ProductDTO> GetRelatedProducts(ProductDTO productDTO)
    {
        ...
    

    视图模型(上面称为服务的东西)背后最重要的想法是它在 UI 和业务模型之间进行调解。换句话说:它以与 UI 相关的方式编排和聚合业务模型。如果用户界面在某个时候想要一个相关产品的列表,那么服务必须提供它。真的就这么简单,商业模式本身是否也有这个概念在这里完全无关紧要。

    HTH! 托马斯

    附: 如果您的 DTO 变得更大并且您的列表更长,您可能会考虑引入另一个(简化的)DTO,其中只有名称和某种标识符,以减少您必须从存储库中检索的不必要数据量。

    【讨论】:

    • 托马斯,感谢您的回答。我编辑了问题并补充说相关产品已经从上述代码的存储库中获取。域模型产品实体有一个列表,其中包含已加载的相关产品。我只是对如何将相关产品放到视图中感到困惑。知道该列表不属于 DTO 会很有帮助,这会使事情变得容易一些。
    • Thomas,我稍微编辑了这个问题,试图让事情变得更清楚一些。如果有时间,可以再看看吗?
    • 如果您的商业模式 - 产品已经有一个 'GetRelatedProducts()' 方法,那么您的 ProductDTO 也可能有这个(返回 ProductDTO 的只读列表)。如果您需要在没有原始 ProductDTO 的情况下将相关产品交付到您的 UI,那么拥有额外的服务方法可能更容易......两者都同样可能和“有效”,这完全取决于您的 UI 中更有意义的内容上下文/工作流程。
    • 是的,目前使用一个数据库事务同时填充产品和相关产品。那么在这种情况下,将 ProductDTO 的只读列表添加到我的 ProductDTO 是有效且有意义的吗?
    • 在这种情况下,听起来那将是最简单和最简单的事情。所以你应该去...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    • 2013-07-28
    • 1970-01-01
    • 2018-05-20
    • 2010-12-25
    相关资源
    最近更新 更多