DDD:保存对模型的更改并访问存储库

zsh*_*arp 2 architecture design-patterns domain-driven-design

我有一个Question对象,它是Question Aggregate的根.该问题与答案实体的总体相关.创建新的Answer对象时,更改将通过存储库保存到DB.我可以调用存储库方法SaveAnswer(问题ID)还是必须调用SaveQuestion(QUestionID)并让存储库确定进行了哪些更改?如果是后者,这是如何实现的?

相反,如果我想加载特定问题的所有答案,我必须调用GetQuestion()然后拉取答案,或者我可以简单地调用GetAnswers(questionID).

TIA

Ste*_*ock 6

首先,我要说这里没有严格的规则,这是我对DDD和存储库访问的理解,但这是一个相当主观的领域......

因此,从DDD的角度来看,在向现有问题添加答案时,您可能想要做的事情类似于以下C#样式伪代码:

using(unitOfWork = new UnitOfWork())
{
  var question = _questionRepository.GetQuestion(questionId);
  question.AddAnswer(new Answer("blah"));
  unitOfWork.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

假设您正在使用处理更改跟踪的ORM,并且配置为将子对象级联回数据库,这是您需要做的所有事情(我在这里考虑NHibernate,但其他ORM可以以类似的方式工作).通过添加问题的答案,您已告知ORM您希望在工作单元完成时将答案保留在数据库中.你通常不会调用SaveAnswer(QuestionId) - 这不是一种以DDD为中心的方式来处理Answer与问题和问题是聚合根相同聚合的事情.

为了将对象从数据库中取出,通常你会向存储库询问一个问题对象(大概是id),然后从那里导航到Answer(通过问题上的Answers集合) - 例如

var question = _questionRepository.GetQuestion(questionId);
foreach(var answer in question.Answers)
{
  Console.WriteLine(answer.Description); // or do something useful instead!
}    
Run Code Online (Sandbox Code Playgroud)

如果这似乎是一种保存或检索Answer对象的奇怪方式,那么您可能想要重新评估Answer是否确实属于同一个聚合,或者是否最好将它完全从问题聚合中删除.