7

我有這個模型實體框架代碼優先5級聯許多刪除多個表錯誤

public class State 
{ 
    public State() 
    { 
     this.Promotions = new List<Promotion>(); 
     this.Branches = new List<Branch>(); 
     this.Stores = new List<Store>(); 
    } 

    public int Id { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<Promotion> Promotions { get; set; } 
    public virtual ICollection<Store> Stores { get; set; } 
    public virtual ICollection<Branch> Branches { get; set; } 
} 

public class Store 
{ 
    public Store() 
    { 
     this.Promotions = new List<Promotion>(); 
     this.Branches = new List<Branch>(); 
    } 

    public int Id { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<Promotion> Promotions { get; set; } 
    public virtual ICollection<Branch> Branches { get; set; } 

    public int StateId { get; set; } // Foreign key 
    public virtual State State { get; set; } // Navigation Property 
} 

public class Branch 
{ 
    public Branch() 
    { 
     this.Promotions = new List<Promotion>(); 
    } 

    public int Id { get; set; } 
    public string Name { get; set; } 
    public int StoreId { get; set; } // Foreign key 
    public int StateId { get; set; } // Foreign key 

    public virtual Store Store { get; set; } // Navigation Property 
    public virtual State State { get; set; } // Navigation Property 

    public virtual ICollection<Promotion> Promotions { get; set; } 
} 

    public class Promotion 
{ 
    public Promotion() 
    { 
     this.Stores = new List<Store>(); 
     this.Branches = new List<Branch>(); 
     this.Productos = new List<Producto>(); 
    } 

    public int Id { get; set; } 
    public string Name { get; set; } 
    public int StateId { get; set; } 

    public virtual ICollection<Store> Stores { get; set; } 
    public virtual ICollection<Branch> Branches { get; set; } 
    public virtual ICollection<Product> Products { get; set; } 

    public virtual State State { get; set; } 

} 

這在我的上下文:

// State 
modelBuilder.Entity<State>() 
    .HasMany(p => p.Promotions) 
    .WithRequired(e => e.State) 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<State>() 
    .HasMany(s => s.Branches) 
    .WithRequired(e => e.State) 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<State>() 
    .HasMany(e => e.Stores) 
    .WithRequired(e => e.State) 
    .WillCascadeOnDelete(true); 

// Store 
modelBuilder.Entity<Store>() 
    .HasMany(b => b.Branches) 
    .WithRequired(s => s.Store) 
    .WillCascadeOnDelete(true); 

// Many to many 
modelBuilder.Entity<Store>(). 
    HasMany(p => p.Promotions). 
    WithMany(s => s.Stores). 
    Map(
    m => 
    { 
     m.MapLeftKey("StoreId"); 
     m.MapRightKey("PromotionId"); 
     m.ToTable("Store_Promotion"); 
    }); 

modelBuilder.Entity<Promotion>(). 
HasMany(e => e.Products). 
WithMany(p => p.Promotiones). 
Map(
    m => 
    { 
     m.MapLeftKey("PromotionId"); 
     m.MapRightKey("ProductoId"); 
     m.ToTable("Promotion_Producto"); 
    }); 

modelBuilder.Entity<Branch>(). 
HasMany(p => p.Promotiones). 
WithMany(b => b.Branches). 
Map(
    m => 
    { 
     m.MapLeftKey("BranchId"); 
     m.MapRightKey("PromotionId"); 
     m.ToTable("Branch_Promotion"); 
    }); 

現在,如果我打開一個以上的WillCascadeOnDelete (流暢映射中的前三個)我得到錯誤

測試方法Proj.Data.Tests.UnitTest1.TestPromotion拋出異常:
System.Data.SqlClient.SqlException:將外鍵約束上表「分支」「FK_dbo.Branch_dbo.Store_StoreId」可能會導致循環或多個級聯路徑。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY約束。 無法創建約束。查看以前的錯誤。

我知道,我已經從朱莉·勒曼的書閱讀:

有些數據庫(包括SQL Server)不支持指定 級聯刪除指向同一個表

多重關係

碰巧因爲多對多的關係表有級聯刪除從兩個相關的表來。

所以,我的問題是:在這裏,唯一的選擇是關閉的父表級聯刪除和手動處理的關係表中刪除?實體框架5沒有任何解決方法嗎?

回答

6

好吧,我明白這個問題。這是不是有一個多對多的關係,問題是這樣的

State -> Promotion -> PromotionStore 
State -> Branch -> BranchPromotion 
State -> Store -> StorePromotion 

然後存儲,分支和存儲有FK到狀態。所以如果我刪除一個國家PromotionStore可以達到第一和第三的可能性。

我最終什麼事做的是手動關閉級聯刪除國家和刪除相關的記錄是這樣的:

public override void Delete(State state) 
{ 
    DbContext.Entry(state).Collection(x => x.Promotions).Load(); 
    DbContext.Entry(state).Collection(x => x.Stores).Load(); 
    DbContext.Entry(state).Collection(x => x.Branches).Load(); 

    var associatedPromotions = state.Promotions.Where(p => p.StateId == state.Id); 
    associatedPromotions.ToList().ForEach(r => DbContext.Set<Promotion>().Remove(r)); 

    var associatedStores = state.Stores.Where(e => e.StateId == state.Id); 
    associatedStores.ToList().ForEach(e => DbContext.Set<Store>().Remove(e)); 

    var associatedBranches = state.Branches.Where(s => s.StateId == state.Id); 
    associatedBranches.ToList().ForEach(s => DbContext.Set<Branch>().Remove(s)); 

    base.Delete(state); 
} 
相關問題