【发布时间】:2011-08-19 10:03:01
【问题描述】:
我们正在使用 EF、WCF 和 jQuery 实现 SOA Web 应用程序。
这是我们架构的简要视图:
------------- ---
| UI | | |
------------- | |
| Services | | D |
------------- | T |
| Businsess | | O |
------------- | |
| Dal | | |
------------- ---
我们知道我们应该有 DTO 类在层之间特别是在服务和 UI 之间传递数据,但是我们在使用 DTO 的方式(发送到 UI 或从 UI 接收)方面存在一些概念性问题。
对于数据驱动项目,我们可以使用 POCO 自动生成 DTO 对象。但在大型应用程序中,它并不是那么简单。
我们知道解决我们问题的两种解决方案:
第一个解决方案(除了手动创建的新 DTO 之外还使用 POCO)
例如,假设我们有一个包含许多字段的实体。并且有一个显示实体记录的查找组合框。我们只需要一个实体键作为组合框值字段,另一个字段(例如标题)作为组合框文本字段。因此,我们创建了一个名为“GetAllItemsTitle”的方法来检索所有实体。现在我们应该只返回我们想要的结构(在这个例子中是一个键和一个值)。所以我们必须创建一个新类来存储该结构(一个键和一个值)。
这将是新的 DTO 类:
[DataContract]
public class SampleManuallyDto
{
[DataMember]
public long Id { get; set; }
[DataMember]
public string Title { get; set; }
}
并且方法签名是这样的:
public List<SampleManuallyDto> GetAllItemsTitle()
第二种解决方案(使用 Nullable 或 Emptyable DTO)
我们可以绕过 POCO 并手动创建 DTO。然后我们可以将 DTO 的所有属性定义为可为空的或类似可以被识别为 Empty 的属性(我称之为 Emptyable)。它允许我们将 DTO 用于多种目的。当然我们需要遵循适配器模式。例如,为那些名为“FromEntity”和“ToEntity”的 Emptyable DTO 创建两个方法,将我们手动创建的 DTO 转换为(实体框架的)EntityObjects。
现在我们可以绕过“第一个解决方案”(GetAllItemsTitle)示例中创建新的 DTO 类。
方法签名是这样的:
public List<SampleDTO> GetAllItemsTitle()
但是在方法体中我们只填充了 SampleDTO 的“Id”和“Title”属性。正如我所说,SampleDTO 的所有属性都可以为空,因此我们只需填充我们想要的属性,而将其他属性留空。
结论
通常,第一个解决方案(除了手动创建的新 DTO 之外还使用 POCO)是 Strongy-Typed。只需查看方法签名(没有额外的属性),就可以简单地找出每个方法返回的数据类型。但是我们担心管理手动创建的 DTO。他们很快就会长大。
但第二种解决方案是一种更动态的方式,识别从“GetAllItemsTitle”返回的内容的唯一方法是查看方法主体或其文档。所以我们担心“运行时错误”。开发人员可能会假设属性为空时不应为空。
此外,我们在将数据从 UI 中“放入”服务时遇到此类问题的表达示例。例如对于更新和插入以及其他此类操作。即使是“搜索条件”,我们也有相同的选择。
抱歉,问题太长了。 请帮助我们提出您的善意建议。
【问题讨论】:
标签: wcf architecture entity-framework-4 poco dto