如何在 DDD 中对聚合进行建模并持久化到数据库

use*_*711 2 c# domain-driven-design aggregate

我只是想摆脱典型的存储库/服务/演示的 N 层架构的舒适区,并开始研究 DDD 和聚合,我不得不承认我有点困惑,希望有人能澄清以下内容例子:

如果我有一个名为 News、NewsImage 和 Customer 的实体,它们都是 EF 可持久对象,如下所示:

public class Customer
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}

public class NewsImage
{
    public virtual int Id { get; set; }
    public virtual byte[] Data { get; set; }
    public virtual News News { get; set; }
}

public class News
{ 
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual ICollection<NewsImage> NewsImages { get; set; }
    public virtual Customer Customer { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

据我了解,这些可能是我们用来将域对象持久化到数据库的对象,但如果我们使用域模型中的聚合,我们可能会得到如下内容:

public class NewsAggregate
{
    public int Id { get; set; }
    public string Name { get; set }

    public void AddImageToNews(byte[] imageData)
    {
         // Hide NewsImage or that object and add the byte[] data here?
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题如下,我希望得到任何澄清,因为我确信我误解了这里的基本原则:

  1. 只有聚合对象应该暴露给表示层(或任何消费层)。
  2. 我如何处理将聚合对象转换/持久化到数据库,我可以使用映射,这很好,但是我怎么知道我是创建对象还是更新(通过设置 Id 是否是瞬态的?) . 我如何知道是否添加了新图像以及要更新或删除哪些图像?我认为我遇到的问题是我调用 create 将新闻聚合传递给存储库并创建它,然后我可以从通过带有 EF 的实体填充的域中取回聚合,然后在我传递新闻聚合时添加图像返回 我怎么知道为了创建/更新数据发生了什么变化?
    1. 客户应该去哪里,它是否应该作为 AddCustomer 方法在新闻聚合对象上,是否应该有一个具有 AddNews 方法的 CustomerAggregate 以及这两个选项如何持久化?

非常感谢您的任何见解,我一直在阅读并查看示例项目,这些项目展示了这个概念,但似乎并没有完全解释实现这一目标的最佳方法。

Gia*_*sio 5

第一:DDD 不建议您使用任何特定架构。我在 DDD 中使用了许多不同的架构,您应该使用对任务有益的架构。显然,如果你以数据驱动的方式思考,你会遇到很多 DDD 的问题。

DDD 是一种旨在处理复杂业务规则的方法论。如果您的应用程序价值在于技术资产(如在云中、公开 Web 服务或一些漂亮的 html5/移动 UI),则不应该使用它,而在于它处理的业务的复杂性。
您不应该将 DDD 用于简单的业务规则。经验法则是:如果您不需要领域专家来了解业务,那么您根本不需要 DDD。

然后,要正确理解聚合,您应该阅读 Vernon关于该主题文章。那篇文章解释说存在聚合是为了确保业务不变量。你永远不应该仅仅为了优化数据库访问而使用聚合。