在DDD中,通常情况下,您将聚合根下的整个组合层次结构向下并将其视为单个实体。所以,采用这种心态,“如果只添加评论,我为什么要保存文章?”,整篇文章似乎已经发生了变化,并且文章在数据库中的表示形式已过时。理想情况下,您可以替换数据库中的整个组合层次结构(使用文档数据库这样可以),但这可能会导致关系数据库中的性能问题。
在这种情况下,您可能决定让存储库扫描实体组合,聚合根,并智能决定如何处理每个组件。您可以使用访问者模式遍历Comment对象,并根据它们是否为瞬态/脏,决定进行插入或更新,或者仅仅让它们独立。
我希望我已经一直不够清晰,我不太擅长解释概念性的东西:)
编辑:代码示例:
// In ArticleRepository...
public void Save(Article article)
{
// IsTransient (as opposed to IsPersistant) means "has not yet been saved"...
if (article.IsTransient)
{
DB.InsertArticle(article);
// Inserting the article also inserts any comments/sub components...
}
else
{
// IsDirty means "has been modified since it was taken from the DB"...
if (article.IsDirty)
{
DB.UpdateArticle(article);
}
foreach(var comment in article.Comments)
{
if(comment.IsTransient)
{
DB.InsertComment(article.Id, comment);
}
else
{
if (comment.IsDirty)
{
DB.UpdateComment(comment);
}
}
}
}
}
你帮我评论过,因为我意识到我正在做的事情已经存在。所以我改变了方法:我首先使用代码实体框架;并实行工作单位模式。所以现在EF环境正在为我保留这些变化。感谢您的反馈! –
@Dmitry +1这是一个非常有效的点。在我的特殊情况下,我不能对所使用的ORM的功能做任何假设(它甚至可能不是ORM),因此我有必要在域中实现诸如更改跟踪等事情。如果你充分绑定到一个ORM实现,你可以可靠地利用它的功能,那么当然这样做很有意义:) – MattDavey
实际上,我的域不依赖于ORM或其他任何东西。这是洋葱建筑的中心。围绕它构建的工作单元依赖于ORM,并使用其上下文进行更改跟踪。但该域名只有域逻辑... –