填写DTO的正确方法是什么

时间:2011-01-11 12:30:44

标签: c# .net architecture dto

我正在使用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进行查询?

我希望我能说清楚。

谢谢你的帮助!

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

2 个答案:

答案 0 :(得分:6)

我认为这将取决于您的DTO的使用范围以及它们的复杂程度。对于如图所示的简单,在填充所有字段时不太可能产生显着的性能影响,并且它将使得使用公共映射代码变得更容易。对于复杂对象图中的大量数据集来说,这将是一个更大的问题。

我只担心展平物品或取消DTO(假设它们有意义),如果性能确实存在问题,您可以通过进行更改来衡量您将获得的改进。

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

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

答案 1 :(得分:2)

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

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

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

注意:

根据您的问题,我得到您想要使用DTO

的印象
  

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

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

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