2016-06-14 47 views
0

如果我在.NET MVC項目中使用實體框架(數據庫上下文中的dbsets和模型等)有這樣的關係。瞭解.net mvc(實體框架)中特定關係中的級聯刪除?

class A { 
    contains a list of class C objects (one-to-many) 
} 

class B { 
contains a list of class C objects (one-to-many), often many of the 
same class C entries which class A uses aswell 
} 

class C { 
    contains class D elements 
} 

class D { } 

所以,主要的問題是,A級是一個模式,我想作爲數據經常刪除其只應該用於固定的時間量(當時它是由cron作業刪除)存在,但由於某種原因,當我刪除類A條目時,它似乎混淆了類C和類D之間的關係,從數據庫中的類C條目中刪除了類D項。

是否有某種方法可以刪除我的類中的條目數據庫表,同時確保它完全保留所有其他表而無一例外?

我已閱讀禁用級聯刪除,但說實話,我很困惑我應該如何理解在這個特定的上下文中發揮什麼奇怪的關係,我不太確定我應該是什麼禁用它。

我希望這個例子有意義我試圖儘可能簡單地解釋它。

+0

你可以發表一些關於你如何做EF映射的更多細節? –

回答

1

默認情況下,EF啓用了OneToManyCascadeDeleteConvention。這工作就像通過在表之間的外鍵上設置SQL級聯刪除一樣。當主要對象被刪除時,任何外部鍵入該對象的對象也將被刪除。因此,在您的示例中,刪除A時,它也將刪除集合中的所有對象。而且由於級聯,它還將刪除所有這些對象的集合中的所有D對象(假設您的意思是C包含一對多的D對象集合)。

但是,OneToManyCascadeDeleteConvention僅適用於外鍵字段設置爲必需的情況。將其設置爲空(如下例所示)應禁用約定。

public class ObjectA 
{ 
    public int ObjectAId { get; set; } 
    public virtual ICollection<ObjectC> ObjectCCollection { get; set; } 
} 

public class ObjectC 
{ 
    public int? ObjectAId { get; set; } 
    public virtual ObjectA ObjectA { get; set; } 
} 

這就是說,也可以選擇性地使用一個EntityTypeConfiguration實體配置期間除去ObjectA之間的級聯ObjectC

internal class ObjectCMap : EntityTypeConfiguration<ObjectC> 
{ 
    public ObjectCMap() 
    { 
     this.HasOptional(o => o.ObjectA).WithMany(o => o.ObjectCCollection).WillCascadeOnDelete(false); 
    } 
} 

,然後用在DbContext

modelBuilder.Configurations.Add(new ObjectCMap()); 

模型構建器註冊它如果ObjectC外鍵字段不能爲空,但是,SQL會當您嘗試拋出一個外鍵錯誤刪除ObjectA

+0

如何設置外鍵?現在,我只是在「many」模型中使用虛擬icollection 和虛擬來創建一對多關係,實體框架自己命名外鍵(使用自己的外鍵名創建列)。我是否應該將EF爲我選擇的列的名稱聲明爲類中的變量? – ObedMarsh

+0

在這種情況下,您可以使用上面顯示的EntityTypeConfiguration。 HasOptional將使外鍵可以爲空。 – Kevin

+0

只是爲了完整起見,你有第二個選擇,就像你所描述的那樣,在你的模型中創建一個屬性來保存外鍵。這將在上面的示例中繼續「ObjectC」,按照慣例,屬性名稱應該與鏈接到的表上的id字段具有相同的名稱,在本例中爲「ObjectA」。如果您需要屬性名稱不同,則可以使用ForeignKeyAttribute設置要用作外鍵的自定義屬性名稱。這是一個資源,顯示我的意思:http://tektutorialshub.com/data-annotations-foreignkey-attribute-entity-framework/ – Kevin