2015-07-20 30 views
0

我有一個具有可選1對多的關係,定義和配置這樣兩個實體:刪除可選1對多不設置外鍵空

public class A 
{ 
    // ... 
    public int? BId { get; set; } 
    public B B { get; set; } 
} 

public class B 
{ 
    // ... 
    public virtual ICollection<A> As { get; set; } 
} 


public class AConfiguration : EntityTypeConfiguration<A> 
{ 
    public A() 
    { 
     // ... 
     HasOptional(r => r.B).WithMany(r => r.As).HasForeignKey(r => r.BId); 
    } 
} 

當的實體刪除類型BI期望所有具有到B實體的外鍵的類型A的實體被刪除以將該BId外鍵設置爲null。刪除操作正是如此定義:

public void DeleteB(int bId) 
{ 
    var entity = _context.Bs.Single(b => b.Id == bId); 
    _context.Bs.Remove(entity); 
    _context.SaveChanges(); 
} 

然而這並沒有發生。類型B的實體已成功刪除,但A實體上的BId仍然非空,而任何其他對.SaveChanges()的調用都會引發異常,因爲這些BIds正在引用不再存在的行。

如何以刪除BId屬性的方式刪除B實體,而無需在刪除操作期間手動迭代集合?

回答

1

如果當前關聯的實體已經加載到上下文中,外鍵只會自動設置爲空。換句話說,當b被刪除時,如果A類型的實體已被加載到上下文中,那麼A類型的關聯集合只會將其BId屬性設置爲空。否則,EF不會知道它們的存在(除非EF提供程序自動生成SQL,將這些外鍵設置爲空......它不在SQL Server案例中)。

一種選擇是要做到這一點(如果你不介意加載所有這些實體):

public void DeleteB(int bId) 
{ 
    var entity = _context.Bs.Single(b => b.Id == bId); 
    _context.Entry(entity).Collection(b => b.As).Load(); 
    _context.Bs.Remove(entity); 
    _context.SaveChanges(); 
} 

另一種方法是寫自己的SQL語句,並運行。

+0

我可以在A表上運行一個'update A a set a.BId = NULL,其中a.BId = @ bId'作爲''before delete''觸發器。 – user1569339