簡體   English   中英

在實體框架中刪除聚合根的子對象

[英]Deleting a child object of an aggregate root in Entity framework

這可能是以前問過的,但我似乎無法在該站點上找到解決方案,所以我們開始:

這是我的域模型的簡化版本。 我有2個類,代表數據庫中的2個表:

public Class Person
{
    public int Id { get; set;}
    public string Name { get; set;}
    public virtual List<Contact> Contacts { get; set;}

    public void AddContact(string value) 
    {
        //some validation code
        Contacts.Add(new Contact(value));
    }

    public void DeleteContact(Contact contact) 
    {
        //some validation code
        Contacts.Remove(contact);
    }
}

public Class Contact
{
    public int Id { get; set;}
    public string Value { get; set;}
    public virtual Person Person { get; set;}
    public int PersonId { get; set;}
}

現在,“人”是我的總根。 我試圖通過僅使聚合根成為存儲庫來遵循DDD主體。 添加聯系人可以正常工作。

我的問題是刪除聯系人時。 它給出了錯誤:

操作失敗:由於一個或多個外鍵屬性不可為空,因此無法更改該關系。 對關系進行更改時,相關的外鍵屬性將設置為空值。 如果外鍵不支持空值,則必須定義新的關系,必須為外鍵屬性分配另一個非空值,或者必須刪除不相關的對象。

無論如何還有過去。 如果關系屬性為非空值,則實體框架不應自動刪除聯系人。

現在,我知道從集合中刪除與從上下文中刪除並不相同,但是我不想從域模型中引用DbContext。

我只有PersonRepository。

請提供解決方案或幫助我了解是否有錯誤的概念。

看來您遇到的問題與此帖子相同。 基本上,當您從集合中刪除聯系人時,您實際上並沒有將其刪除。 您只是孤立它,在此過程中,將其PersonId設置為null (當然,對於int是不可能的)。

一種可能的解決方案是使ContactId類中的PersonId可為空:

public int? PersonId { get; set; }

然后,在您的DbContext中,覆蓋SaveChanges以自動刪除孤立的記錄:

public override int SaveChanges()
{
    foreach (Contact contact in Contacts.Local.Where(c => c.PersonId == null))
    {
        Contacts.Remove(contact);
    }
    return base.SaveChanges();
}

免責聲明:我尚未測試該代碼,但希望它是一個很好的起點。

在使用EF進行DDD時,這是一個常見的問題。 到目前為止,有兩種解決方案對我來說效果很好:

  1. DeleteContact方法返回刪除的實例。 該方法最有可能從擁有存儲庫的應用程序服務中調用。 然后,您可以使用它從DbContext中刪除實例。

  2. 如果您使用域事件 ,則可以使用一個事件來通知其他人有關聯系人刪除的信息。 然后,您可以在基礎結構層中放置此事件的處理程序,該處理程序將從DbContext中刪除該聯系人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM