【问题标题】:How update an entity inside Aggregate如何更新聚合内的实体
【发布时间】:2011-07-07 22:27:06
【问题描述】:

我有一个名为 Campaigns 的聚合,每个都有一个名为 Campaign 的根实体,这个根实体有一个尝试列表(实体)

    public class Attempts: IEntity<Attempts>
    {
        private int id;
        public AttempNumber AttemptNumber {get;}
        //other fields 
    }

    public class Campaign: IEntity<Campaign> //root
    {
        private int id;
        public IList<Attempt> {get;}
        //other fields 
    }

我正在使用一种方法来添加广告系列尝试

 public virtual void AssignAttempts(Attempts att)
        {
            Validate.NotNull(att, "attemps are required for assignment");

            this.attempts.add(att);
        }

当我尝试编辑尝试列表中的特定项目时出现问题。我通过 AttempNumber 获得尝试并将其传递给 editAttempt 方法,但我不知道如何在不删除整个列表并重新创建它的情况下设置尝试

 public virtual void EditAttempts(Attempts att)
 {
        Validate.NotNull(att, "attemps are required for assignment");
 }

任何帮助将不胜感激!

谢谢, 佩德罗·德拉克鲁斯

【问题讨论】:

    标签: domain-driven-design ddd-repositories


    【解决方案1】:

    首先,我认为您的域模型可能有一点问题。在我看来,“活动”应该是一个聚合根实体,具有“尝试”值对象(或实体)的集合。除非您有一个包含一系列广告系列的广告系列的父概念,否则没有“广告系列”聚合。此外,没有“尝试”实体。而是“尝试”实体或“活动”实体上的值的集合。如果“尝试”在“活动”之外具有身份,则它可能是一个实体,否则它是一个值对象。代码可能是这样的:

    class Campaign {
        
        public string Id { get; set; }
        
        public ICollection<Attempt> Attempts { get; private set; }
        
        public Attempt GetAttempt(string id) {
            return this.Attempts.FirstOrDefault(x => x.Number == id);
        } 
        
    }
        
    class Attempt {
        public string Number { get; set; }
        public string Attribute1 { get; set; }
    }
    

    如果您从 Campaign 实体中检索 Attempt,然后更改某些属性,则不必将其重新插入到活动实体中,因为它已经存在。如果您使用 NHibernate,这就是代码的外观(其他 ORM 类似):

    var campaign = this.Session.Get<Campaign>("some-id");
        
    var attempt = campaign.GetAttempt("some-attempt-id");
        
    attempt.Attribute1 = "some new value";
        
    this.Session.Flush(); // will commit changes made to Attempt 
    

    【讨论】:

    • campaign 聚合根 (AR) 之外修改 attempt 将打破所有修改必须通过聚合根的规则。否则 AR 将无法控制内部状态,整个设计模式将毫无用处。
    【解决方案2】:

    您不需要 Edit 方法。您的代码可以就地修改尝试,如下所示:

    Attempt toModify = MyRepository.GetAttemptById(id);
    toModify.Counter++;
    toModify.Location = "Paris";
    MyRepository.SaveChanges(); // to actually persist to the DB
    

    当然,如何命名 SaveChanges() 取决于您,这是 Entity Framework 命名其通用 Save 方法的方式。

    【讨论】:

    • 它打破了聚合根的规则,从内部持有对某物的引用并直接从外部修改它。所有修改都必须通过聚合根的方法来执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多