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); 
} 
相关问题