【问题标题】:What is the right way to fill DTOs填写 DTO 的正确方法是什么
【发布时间】:2011-06-07 03:44:40
【问题描述】:

我正在使用 DTO(数据传输对象)在应用程序的不同层之间传输信息。

就性能和填充这些对象的方式而言,最佳做法是什么?我是否应该使用与我的数据访问层不同的方法只填写最低要求的信息?

假设我有以下课程:

public class Order
{
    public int OrderNo;
    public Customer Customer;
    public double Total;
}

public class Customer
{
    public int CustId;
    public string CustName;
    public Country Country;
}

public class Country
{
    public int CountryId;
    public string CountryName;
}

如果我需要生成包含 OrderNo、CustName 和 CountryName 的订单列表,而在另一种情况下,不同的信息可能来自不同的表(或 DTO),会发生什么情况?最好使用仅包含必填字段的扁平 DTO 还是使用 LINQ 进行查询?

我希望我说得足够清楚。

感谢您的帮助!

编辑: 我想知道是否应该填充所有嵌套对象,而不仅仅是对象的部分属性。

【问题讨论】:

  • 您能否澄清您的问题中“层”一词的用法?通常,您使用 DTO 在进程和机器之间传输数据。层通常被称为代码的逻辑结构。例如,在由单台机器提供服务的 Web 应用程序中,让您的数据访问层返回丰富的业务对象而不是 DTO 是完全可以的。有关此主题的起点,请参阅 Wikipedia
  • @Marijn:我有一个简单的 3 层 Web 应用程序,其中包含一个表示、一个业务逻辑和一个数据访问层,但我正在使用这个小应用程序来弄清楚如何在我们公司包含 400 多个表,并且将对其中许多表进行大量不同的操作和查询。

标签: c# .net architecture dto


【解决方案1】:

我认为这将取决于您的 DTO 的使用范围和复杂程度。对于所示的简单字段,填充所有字段不太可能对性能产生重大影响,并且可以更轻松地使用通用映射代码。对于复杂对象图中的海量数据集,这将是一个更大的问题。

如果性能确实是一个问题,并且您可以衡量通过更改获得的改进,我只会担心扁平化对象或取消 DTO(假设它们完全有意义)。

关于填充 DTO,我们在多层 ASP.NET MVC 应用程序中广泛使用 LINQ 和 AutoMapper。在我们的业务对象和传递给视图的哑视图模型对象之间进行映射时,AutoMapper 非常有用。虽然我们没有世界上最大的数据库,但我们有一个相当复杂的架构,并且没有因为映射而真正遇到任何性能瓶颈。

我们看到性能问题的一个地方是过早评估的 LINQ 查询,这些查询会拉回大量对象图,而不仅仅是需要的。通过检查是否在正确的时间执行了“选择新”,我将通过网络从数据库中提取 850 MB 数据的查询减少到 1.3 MB!

【讨论】:

    【解决方案2】:

    在我看来,如果您想跨机器或流程传输信息,您只需要 DTO [参见 Fowler's definition]。例如:当您想在与服务器通信的富客户端中使用您的(部分)业务逻辑时,或者当您将数据访问处理与业务处理物理分离时。当您希望在同一台机器上的进程之间共享信息时,DTO 也很有用。

    在这些情况下,我会使用 Linq 或其他自定义代码从业务对象创建 DTO。 @Tim 建议的 AutoMapper 也很有用。

    IMO 设计 DTO 是设计远程接口的一部分。您不希望其中包含任何不必要的信息,以节省处理时间和网络流量。这可能是“扁平化”的情况。另一方面,您不希望以更“健谈的界面”为代价来缩小 DTO。

    注意:

    从您的问题中,我得到的印象是您想使用 DTO 来

    从您的数据中传输信息 访问您的业务对象的层 在您的业务层中

    在我看来,这对于很多很多 Web 应用程序来说都不是问题,其中数据访问和业务逻辑都在同一台机器上、在同一个进程中执行。您不需要 DTO 来从数据库中检索业务对象 - 而是直接将您的实体保存在数据库中和从数据库中取出。为此,您可以使用 ORM 工具或自定义数据访问代码。

    在业务层和表示层之间共享信息也不一定需要 DTO。

    【讨论】:

    • 有趣的相关问题:poco-vs-dto | what-is-data-transfer-object 有趣:一个答案建议在 MVC 中使用 DTO 作为模型(我称之为视图模型)
    • 您能否举例说明如何“将实体直接存入和存入数据库”。谢谢。
    • 在 .net 中,我将使用 ORM 工具 NHibernate 创建一个带有 repositories 的数据访问层。开始使用 NHibernate 时,FluentNHibernate 很棒。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 2011-03-26
    • 1970-01-01
    • 2010-11-22
    • 2017-04-20
    • 1970-01-01
    相关资源
    最近更新 更多