我正在使用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进行查询?
我希望我能说清楚。
谢谢你的帮助!
编辑 我想知道的是,我是否应该填充所有嵌套对象,而不仅仅是对象属性的一部分。
答案 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。