pol*_*kyg 7 entity-framework code-first ef-code-first entity-framework-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; }
}
Run Code Online (Sandbox Code Playgroud)
这在我的背景下:
// 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");
});
Run Code Online (Sandbox Code Playgroud)
现在,如果我打开多个状态的WillCascadeOnDelete(流畅映射中的前三个),我会收到错误
测试方法Proj.Data.Tests.UnitTest1.TestPromotion抛出异常:
System.Data.SqlClient.SqlException:在表'Branch'上引入FOREIGN KEY约束'FK_dbo.Branch_dbo.Store_StoreId'可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.无法创建约束.查看以前的错误.
我知道,我从Julie Lerman的书中读到:
某些数据库(包括SQL Server)不支持指定指向同一表的级联删除的多个关系
因为它发生了,因为多对多关系表具有来自两个相关表的级联删除.
所以,我的问题是:这里唯一的选择是关闭父表上的级联删除并手动处理关系表上的删除?实体框架5是否有针对此的解决方法?
好的,我明白了这个问题.它不是有多对多的关系,问题是这个
State -> Promotion -> PromotionStore
State -> Branch -> BranchPromotion
State -> Store -> StorePromotion
Run Code Online (Sandbox Code Playgroud)
然后Store,Branch和Store有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);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12804 次 |
最近记录: |