数据传输组织

我正在构建一个 Web 应用程序,我希望扩展到许多用户。另外,我需要通过 Web 服务向受信任的第三方公开功能。

我使用 LLBLGen 生成数据访问层(使用 SQL Server 2008)。目标是构建一个业务逻辑层,使 Web 应用程序免受 DAL 细节的影响,当然,还要提供超出 DAL 的额外级别的验证。另外,据我目前所知,Web 服务本质上是 BLL 上的一个薄包装器。

当然,DAL 有它自己的一组实体对象,例如 CustomerEntity、ProductEntity 等等。但是,我不希望表示层直接访问这些对象,因为它们包含 DAL 特定的方法,并且程序集特定于 DAL 等等。因此,我们的想法是创建数据传输对象 (DTO)。这个想法是,本质上,这些将是普通的旧 C#/.NET 对象,它们具有 CustomerEntity 的所有字段,这些字段实际上是数据库表 Customer,但没有其他内容,除了一些 IsChanged/IsDirty 属性。因此,会有 CustomerDTO、ProductDTO 等。我假设这些将从 DTO 基类继承。我相信我可以使用 LLBLGen 的一些模板生成这些,但我还不确定。

因此,BLL 将通过接受和返回这些 DTO 对象来公开其功能。我认为 Web 服务将处理将这些对象转换为 XML 供第三方使用它,许多人可能不使用 .NET(此外,有些东西可以使用 JSON 从 Web 应用程序上的 AJAX 调用进行脚本调用)。

我不确定设计这个的最佳方法以及具体如何前进。这里有一些问题:

1) 应如何将其公开给客户端(表示层和 Web 服务代码)

我认为会有一个具有这些方法的公共类,每次调用都是一个原子操作:

InsertDTO、UpdateDTO、DeleteDTO、GetProducts、GetProductByCustomer 等等...

然后客户端只需调用这些方法并传入适当的参数(通常是 DTO)。

这是一个好的、可行的方法吗?

2)这些方法返回什么?显然,Get/Fetch 类方法将返回 DTO。但是插入呢?签名的一部分可以是:

InsertDTO(DTO dto)

但是,插入时应该返回什么?我希望收到错误通知。但是,我对某些表使用自动增量主键(但是,一些表具有自然键,特别是多对多的表)。

我想到的一个选择是 Result 类:

class Result
{
    public Exception Error {get; set;}
    public DTO AffectedObject {get; set;}
}

因此,在插入时,DTO 将获取其 get ID(如 CustomerDTO.CustomerID)属性集,然后放入此结果对象中。如果 Result.Error != null,客户端就会知道是否存在错误,然后它会从 Result.AffectedObject 属性知道 ID。

这是一个好方法吗?一个问题是,它似乎来回传递了大量冗余数据(当它只是 ID 时)。我不认为添加“int NewID”属性会很干净,因为某些插入不会有这样的自动增量键。另一个问题是我认为 Web 服务不能很好地处理这个问题?我相信他们只会返回 Result 类中 AffectedObject 的基本 DTO,而不是派生的 DTO。我想我可以通过拥有很多不同类型的 Result 对象(可能从基本 Result 派生并继承 Error 属性)来解决这个问题,但这看起来不太干净。

好吧,我希望这不会太罗嗦,但我想说清楚。

有帮助吗?

解决方案

1:这是一种非常标准的方法,非常适合最佳可单元测试方法的“存储库”实现。

2:异常(顺便说一句,应该在 WCF 边界上将其声明为“错误”)将自动引发。您不需要直接处理它。对于数据 - 有三种常见的方法:

  • 使用 ref 在合同上(不是很漂亮)
  • 返回(更新的)对象 - 即 public DTO SomeOperation(DTO item);
  • 仅返回更新的身份信息(主键/时间戳/等)

所有这些的一件事是,每个操作不需要不同的类型(对比您的 Result 类,每个 DTO 都需要复制该类)。

其他提示

Q1:你可以把你的WCF数据契约复合类型的DTO的作为来解决这个问题。这样,你的UI层只具有访问DataContract的DataMember属性。你的原子操作将是你的WCF接口暴露的方法。

Q2:配置您的响应数据的合同,以返回与您的主键等新的自定义类型... WCF也可以被配置成泡例外回UI

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top