2011-12-16 29 views
4

我有一個域模型與聚合根:如何避免在添加子實體時持久化整個聚合根?

public interface IAggregateRoot { 
    public string Id { get; } 

    public string Foo { get; set; } 
    public int Bar { get; set; } 

    public IList<IChildEntity> Children { get; } 
} 

兒童收集往往會非常大,我會延遲加載它,當一個IAggregateRoot例如通過IAggregateRootRepository檢索。我的問題是這樣的;如果我想將IChildEntity添加到IAggregateRoot的Children集合中,我的存儲庫如何避免保留整個集合?

例如,假設我IAggregateRootRepository分別來看看如下所示:

public interface IAggregateRootRepository { 
    public IAggregateRoot GetById(string id); 

    public void AddOrUpdate(IAggregateRoot root); 
} 

然後,我可以通過打通IAggregateRootRepository.GetById()的IAggregateRoot實例添加到Children集合,增加孩子的子集合,然後通過IAggregateRootRepository.AddOrUpdate()持久化。但是,每當我添加一個子實體時,它就會堅持整個聚合根,連同其龐大的子集。我想我可以得到解決,如果我的倉庫看起來像:

public interface IAggregateRootRepository { 
    public IAggregateRoot GetById(string id); 

    public void AddOrUpdate(IAggregateRoot root); 
    public void AddOrUpdate(IChildEntity child); 
} 

但是,正如我已經明白了存儲庫模式,資源庫應該只處理總根,上面肯定的解決方案打破了要求。

還有其他更好的方法可以避免這個問題嗎?

回答

5

聚合根應該圍繞寫邊界進行設計 - 也就是說,任何通常在單個批次/事務中寫入數據庫的內容。如果你發現你需要單獨堅持不是根的子實體,那麼可能是時候重新考慮你的設計,並且讓你的子實體成爲一個獨立的聚合根本身(因爲它具有單獨的寫入邊界)。

您的原始聚合根將不包含子實體,而是對它們的引用(因爲它們現在聚合根本身 - 聚合根之間的鏈接應通過引用鍵)。這也有助於您的懶惰加載策略。

希望幫助:)

+0

如何獲取兒童的名單?它是原始的AggregateRootRepository還是新的ChildAggregateRepositroy的工作?或者這是否意味着子集合現在需要知道如何在父實體中加載自己? – Eatdoku 2012-09-28 22:54:30

-1

通常情況下,ORM負責整個聚合體的更新到數據庫中。它檢測檢索到的實體中所做的更改,並且只會持續聚合的修改後的實體。

因此,如果您只向根添加子項,並且您沒有對聚合進行其他修改。然後,ORM將只爲子實體插入一條新記錄,並保留根集合,並且僅保留其他子記錄。

相關問題