C# 我应该避免使用聚合根吗?

C# 我应该避免使用聚合根吗?,c#,nhibernate,domain-driven-design,C#,Nhibernate,Domain Driven Design,问题 有四个实体: class Product : Entity<Product> { public virtual String Title { get; set; } public virtual Category Category { get; set; } public virtual Vendor Vendor { get; set; } } class Category : Entity<Category> { /* properti

问题

有四个实体:

class Product : Entity<Product> {
    public virtual String Title { get; set; }
    public virtual Category Category { get; set; }
    public virtual Vendor Vendor { get; set; }
}

class Category : Entity<Category> { /* properties */ }
class Vendor : Entity<Vendor> { /* properties */ }
类产品:实体{
公共虚拟字符串标题{get;set;}
公共虚拟类别{get;set;}
公共虚拟供应商{get;set;}
}
类类别:实体{/*属性*/}
类供应商:实体{/*属性*/}
这四个组件都不被定义为组件,我不知道应该使用哪一个(用
IAggregateRoot
接口标记它)作为聚合根

我需要方便地访问供应商列表,类别,以显示在页面上,同时创建一个新产品

然后,根据这些实体,似乎应该有三个
存储库
实例

旁白


我看过几个大型项目。他们大量使用独立实体列表,如供应商、州、技术选项。我认为用聚合根设计东西是合乎逻辑的,但我不知道DDD原则是否适用于那里。

它们看起来像不同的聚合,可以通过应用级联删除规则来确认:

级联删除规则有时被引用为判断您是否有一组实体或VO应为聚合的好方法–如果父项被删除,则下面该聚合的所有其他部分也将被删除。 因此,如果一个被删除的父对象也会删除所有的子对象,这是没有意义的,那么你没有一个聚合,你只有一个好的老式引用


在您的情况下,如果某个产品被删除,您不希望级联删除所有相关类别,因为它们可能与其他产品相关(您可以将此规则应用于其他实体)。因此,您可能会为它们中的每一个都有一个存储库

您不应该让一个AR引用另一个AR引用的实例。而是通过ID引用或使用值对象


然后尽量不要查询您的域模型,因为这会导致一些懒惰的加载和其他讨厌的设计。而是创建一个瘦查询层来返回所需的数据。您甚至可能希望对查询层的某些数据进行非规范化,以提高性能。

。。。你真的在使用NHibernate或类似的东西吗?@Stefan:通常我会避开ORMs。我确实执行我自己的映射,但在另一个映射中有AR的实例通常会导致花哨的步法w.r.t.“抓取策略”:)为什么需要使用标记接口?将某物标记为
IAggregateRoot
有什么好处?这只是一种惯例而已。通过使用签名,如
IRepository,其中T:IAggregateRoot
,您可以约束您的存储库,以便只有聚合根可以从存储库中访问。我同意这一点-通常(更简单)说,如果删除聚合根时实体没有存在的理由,则实体属于聚合。