C# 数据层和 Dto

Posted

技术标签:

【中文标题】C# 数据层和 Dto【英文标题】:C# Data Layer and Dto's 【发布时间】:2011-04-26 19:59:34 【问题描述】:

我最近加入了一家使用类型化数据集作为其“Dto”的公司。我认为他们真的很垃圾,想把它改成更现代和用户友好的东西。所以,我正在尝试更新代码,使数据层更通用,即使用接口等,其他人不知道 Dto 是什么,我们对它应该如何完成略有不同。

在不试图让人们接受我的思维方式的情况下,我想从你们那里得到关于 Dto 可以存在于哪些层的公正答案。所有层; DAL、BL 和 Presentation 或这些层中的一个小子集。

此外,IList 对象是否应该出现在 DAL 中。

谢谢。

【问题讨论】:

@leppie : 见rlacovara.blogspot.com/2009/03/… 数据传输对象 - 业务域对象(或多个对象)的轻量级和(通常)上下文无关版本。 对不起,leppie,我不应该假设每个人都知道首字母缩略词。 【参考方案1】:

一件事是DataSets 很难实现互操作性。在使用来自非 .net 客户端的类型化数据集时,即使类型化数据集也不那么兼容。请参阅this link。如果您必须实现互操作性,那么请努力争取 DTO,否则请尝试让您的团队在一段时间内了解 DTO,因为数据集毕竟不是那么糟糕。

在部分接口上,是的,您应该公开接口。例如 - 如果您从 DAL 返回 List<T>,则应返回 IList<T>。有些人只返回IEnumerable<T>,因为您需要的只是枚举能力。但是在这样做的时候不要变成astronaut architect。

在我的应用程序中,我发现返回 IList<T> 而不是 List<T> 会用如下代码污染我的代码库:

//consider personCollection as IList<Person>
(personCollection as List<Person>).ForEach(//Do Something)

所以我个人尝试在返回接口或具体对象之间保持平衡。如果你问我现在在做什么,那么我会告诉你我正在返回List&lt;T&gt;。我被影响不要成为astronaut architect。

【讨论】:

没有返回通用列表msdn.microsoft.com/en-US/library/ms182142(v=VS.80).aspx 是有原因的。这取决于返回 List 的对象是公共的还是私有的。只要您不在公共界面上公开 List 就没有关系,因为只有您在使用它。 是的,如果 public 意味着被您的应用程序之外的人使用,我同意。 Public 不应该被推断为访问说明符,并且如果公共返回类型总是被项目中的某个层使用,并且在一个应用程序之外永远不会看到光,那么将其公开为接口也没有任何意义。【参考方案2】:

我总是使用 DTO,从不使用 DataTable。但我只使用它们从 BL 转移到 DL,反之亦然。在面向服务的情况下,我的表示层通常只知道业务和服务层。

我可以看到使用 DTO 而不是数据表的好处:

轻松重构 简单的图表制作 更清晰、更易读的代码,尤其是在 DAL 的单元测试中

【讨论】:

感谢 vc - 直奔我的问题,将 Dto 捆绑到 IEnumerable 或类似的任何意见? 您的意思是例如允许 DAL 中的 GetCustomers 方法返回 CustomerDTO 的 IList 或 IEnumerable?如果是这样,我看不出您有任何不应该允许的理由。 谢谢 vc - 这正是我的意思【参考方案3】:

根据定义,DTO 是一个数据传输对象,用于(等待)将数据从一层传输到另一层。

DTO 可以跨所有层使用,我已经很好地将它们与 Web 服务一起使用。

【讨论】:

谢谢 Burt,我喜欢你“揭示”什么是 DTO 的方式 :) 别担心,看看领域驱动设计,因为其中包含 DTO。有一些很好的例子说明如何使用 DDD 构建具有复杂业务规则的解决方案。 这里有几个链接给你dddpds.codeplex.comncommon.codeplex.com【参考方案4】:

这真的取决于你的架构。

在大多数情况下,您应该尝试对接口进行编码,那么您的实现是什么并不重要。如果您返回 ISomething,它可能是您的 SomethingEntity 或您的 SomethingDTO,但您的消费代码并不关心,只要它实现了接口。

您应该通过具体的集合或数组返回 IList/ICollection/IEnumerable。

Properties should not return arrays Do not expose generic lists

您首先应该尝试做的是分离您的代码,并通过在您的层之间插入一些接口(例如 DataAccess 层的存储库)使其松散耦合。然后,您的存储库返回由接口封装的实体。这将使您的代码更具可测试性,并允许您更轻松地模拟。一旦您的测试到位,您就可以开始以较小的风险更改实施。

如果您确实开始使用接口,我建议尽早集成 IoC,例如 Windsor。如果你从一开始就这样做,以后会更容易。

【讨论】:

这更像是我想要走的路线,尤其是 IoC 和依赖注入技术,事实上,这就是我试图解释办公室中其他开发人员的内容。

以上是关于C# 数据层和 Dto的主要内容,如果未能解决你的问题,请参考以下文章

DTO中的继承和自定义逻辑[关闭]

测试数据库调用 C#

测试数据库调用 C#

C# AutoMapper6.1.1使用

通过 id 实例化 dto 对象,其中对象作为有效负载 C#

DTO命名约定、建模和继承