1

显然我说 DDD 在实用性上类似于 EAV/CR 是错误的,但到目前为止我看到的唯一区别是为每个实体构建的物理表具有大量连接,而不是三个表和大量连接。

这一定是由于我缺乏对DDD的理解。 在导入数据时,如何将这些对象物理存储到数据库中而不会产生重大的连接和复杂性? 我知道您可以简单地创建输入到您的存储库的对象,但是很难训练像 Microsoft Sql Server Integration Server 这样的工具来使用您的自定义 C# 对象和框架。也许这应该是我的问题,您如何将您的 DDD ASP.NET C# 框架与 Microsoft SQL Server 集成服务和报表服务一起使用?哈哈。

在 EAV/CR 数据库中,我们可以根据人员类型设置具有不同类的单个人员表:供应商、客户、买方、代表、公司、清洁工等。三个表,一些连接,属性始终是字符串在我们插入之前进行验证,就像 MVC 中的 ModelValidation 一样,对象接受任何值但在它有效之前不会持续存在。

在标准的关系模型中,我们曾经为每种类型的实体创建一个表,并混合了像 City 这样的冗余数据类型。

使用领域驱动设计,我们使用对象来表示每种类型的实体、每种类型的 ValueObject 的嵌套对象,以及更多嵌套对象仍然是必要的。在我的理解中,这会为每种实体生成一个表,为每种信息集(值对象)生成一个表。对于所有这些表,我看到了很多连接。我们最终还为每种新的联系人类型创建了一个物理表。显然有更好的方法,所以我在如何将对象持久保存到数据库方面一定是不正确的。

我的供应商看起来像这样:

public class Vendor {
    public int vendorID {get; set;}
    public Address vAddress {get; set;}
    public Representative vRep {get;set;}
    public Buyer vBuyer {get; set;}
}

我的买家:

public class Buyer {
   public int buyerID {get; set;}
   public Address bAddress {get; set;}
   public Email bEmail {get; set;}
   public Phone bPhone {get; set;}
   public Phone bFax (get; set;}
}

我们真的引用了 Vendor.vBuyer.bPhone.pAreaCode 之类的东西吗?我想我们会引用和存储 Vendor.BuyerPhoneNumber,并构建对象几乎就像这些部分的别名:Vendor.Address1、Vendor.Address2、Vendor.BuyerPhoneNumber ... 等等。

4

4 回答 4

1

您可以将对象序列化为 xml 并将其保存到 Sql Server 中的 xml 列中。毕竟,您正在尝试表示分层数据结构,而这正是 xml 擅长的地方。

于 2010-02-16T15:25:44.680 回答
1

领域驱动设计的支持者通常建议让数据模型尽可能接近对象模型,但这并不是一个铁定的规则。

如果您在对象关系映射层中创建映射以将数据转换(投影)到对象中,您仍然可以使用EAV/CR 数据库设计。

决定如何设计您的对象并提供对子值的访问实际上是一个单独的问题,您必须根据具体情况来解决。Vendor.BuyerPhoneNumber还是Vendor.vBuyer.bPhone.pAreaCode?答案始终取决于您,因为它植根于您的特定要求。

于 2010-02-16T15:56:54.010 回答
1

真正的答案是将您的 SQL 规范化策略与您的对象相匹配。如果您有很多重复的地址,并且需要将它们关联在一起,则将数据规范化到单独的表中,从而产生对值对象的需求。

于 2010-02-19T18:28:52.753 回答
0

存储域对象的最佳方法之一实际上是文档数据库。它工作得很好,因为文档的事务边界与聚合根的一致性边界完美匹配。您不必担心 JOIN 或急切/延迟加载问题。但是,如果您应用 CQRS(我在下面写过),这并不是绝对必要的。

缺点通常是查询。如果您想直接查询域对象背后的持久数据,您可能会陷入困境。然而,这是 CQRS 旨在为您解决的复杂性,您的应用程序的不同部分执行查询,而不是加载/验证/存储域对象的部分。

您可能有一个复杂的“命令”实现,它加载域对象,调用它们的行为(记住域对象必须有行为并封装它们的数据,否则可能会变得“贫血”),然后再保存它们,甚至可以选择发布关于发生了什么。

然后,您可以使用这些事件来更新其他一些“读取存储”,尽管您不必这样做。关键是你在你的应用程序中实现了一个完全不同的垂直切片,它不必为复杂的对象模型/ORM业务而烦恼,而是直接进入数据,准确加载它需要的内容并将其返回以显示给用户。

CQRS并不难,也不复杂。它所做的只是指示您使用单独的代码:

  1. 处理命令(改变状态,因此需要涉及的业务规则/不变量)。
  2. 执行查询(不会改变状态,因此不需要涉及所有复杂的业务规则/不变量,因此可以“只是”以有效的方式获取数据。
于 2019-02-26T10:35:47.973 回答