【问题标题】:Understanding why we use data transfer objects for data contracts in place of database entites了解为什么我们将数据传输对象用于数据合约而不是数据库实体
【发布时间】:2014-03-22 15:52:00
【问题描述】:
在使用 Web 服务的客户端正在查找当前与数据库实体一对一匹配的数据的情况下(即 GetAccount、GetTransactions);我们仍然想使用数据传输对象 (dto) 将两者解耦,以允许数据库实体在需要时进行更改,而不会使更改波及整个系统?如果是这样,从消费的角度来看,我们不希望客户端的模型直接基于数据传输对象。我们希望将从 Web 服务返回的任何内容转换为本地模型,原因与我们最初使用 DTO 的原因相同吗?我有这个权利吗?
【问题讨论】:
标签:
asp.net-mvc
wcf
entity-framework
decoupling
【解决方案1】:
DTO 与您要传输的数据的形状相匹配。如果这与底层数据模型匹配,那就这样吧,但那是由。您可能会在某个时候更改底层数据模型的形状,但 DTO 不会改变。
此外,DTO 是由 Web 服务传递给客户端的内容。如果您在服务器上定义了数据模型,那么您不希望分布式客户端必须了解该数据模型。
最后,您的实体类可能包含额外的逻辑,而 DTO 只是公开数据的属性而已。
【解决方案2】:
您的应用程序可以有许多概念层。数据层、业务层、服务层、表示层等等。每个都有一个带有输入和输出的特定功能。目标是如何设计一个松散耦合的系统(即事物之间不会严重依赖彼此,因此任何更改都是孤立的并且影响最小)。您希望最大限度地提高可维护性、提高重用性并最大限度地提高速度。诀窍是降低复杂性,但建立一些基本的分离,使您可以根据需要轻松推进设计。记住雅格尼!你不会需要它!人们倾向于寻找和设计最复杂的架构来解决他们永远不会遇到的问题!我听过多少次“我们有一个单独的数据层,所以我们将来可以换出数据库”......但我从未见过这种情况发生!一个简单的存储库模式就可以工作。
根据之前的海报,您在数据库中(在物理模型中)有数据,您希望将这些数据转换为概念模型,并将其转换为应用程序。然后,任何客户都会使用您的概念模型。我会在您的应用程序代码从数据层从数据库中检索数据时或之后立即执行此操作。这可确保对数据库所做的任何更改都与应用程序的其余部分隔离。因此,您不必开始更改用户界面,因为您已经更改了数据库字段的名称。你只需要更新你的数据层。
如果您选择实体框架作为您的数据访问策略,它会将您的数据库映射到您的概念模型。如果您要将其他数据对象从一种类型转换为另一种类型,请查看 AutoMapper 等技术。您可以将您的实体框架 POCO 映射到服务合同 (XSD)。从客户端的角度来看,“您可以”编写一个调用您的 Web 服务的客户端代理,将返回的服务合同映射到一个很好的共享概念对象模型。
保持简单。将重复使用和简单性作为您选择的核心。如果您开始在客户端对象中看到数据库列名称,则需要开始考虑在解决方案中更早的时候放入一些抽象,以使您的应用免受更改。