我有以下域类:
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类型的List,填充它并将其传递给视图。
这是好主意还是坏主意?为什么呢?
由于
答案 0 :(得分:2)
我根本不会将列表放在DTO中,因为它自然不属于那里。我也不确定你对'包装类'的意思。您只需要一个产品列表,并且在服务上使用另一个返回此列表的方法是完全可以的。
因此,您的服务中会有类似的内容:
public IList<ProductDTO> GetRelatedProducts(ProductDTO productDTO)
{
...
viewmodel(上面称为 service 的东西)背后最重要的想法是它介于UI和业务模型之间。换句话说:它以与UI相关的方式编排和聚合业务模型。如果用户界面想要在某个时刻获得相关产品的列表,那么该服务必须提供它。这真的很简单,而且商业模式本身是否也有这个概念与此完全无关。
HTH! 托马斯
P.S。 如果您的DTO变得更大并且列表更长,您可以考虑引入另一个(简化的)DTO,其中只包含名称和某种标识符,以减少您必须从存储库中检索的不必要数据的数量。