2016-12-15 69 views
1

我所遇到的其中循环引用是不可避免的情况下的情况下,我有三个模型类:教授,模块,元素:循环引用实体框架参考约束失败删除条目教授

  • 教授负责零或许多模块
  • 模块具有零个或一个负责教授
  • 模块可以包含几个或没有元素
  • 每个元素是由一个或零教授是教导

我的模型类:

public class Professor{ 
    public Professor(){ 
     this.Modules = new HashSet<Module>(); 
     this.Elements = new HashSet<Element>(); 
    } 
    public int ProfessorID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public DateTime DayOfBirth { get; set; } 
    public string Email { get; set; } 
    public string Password { get; set; } 
    public string PhoneNumber { get; set; } 
    public virtual ICollection<Module> Modules { get; set; } 
    public virtual ICollection<Element> Elements { get; set; } 
} 

public class Module { 
    public Module() { 
     this.ModuleElements = new HashSet<Element>(); 
    } 
    public int ModuleID { get; set; } 
    public string Title { get; set; } 
    public virtual Professor ResponsibleProfessor { get; set; } 
    public int? ProfessorID { get; set; } 
    public virtual ICollection<Element> ModuleElements { get; set; } 
} 

public class Element { 
    public int ElementID { get; set; } 
    public string Title { get; set; } 
    public int? ProfessorID { get; set; } 
    public int ModuleID { get; set; } 
    public virtual Module Module { get; set; } 
    public virtual Professor Professor { get; set; } 
} 

我的DbContext:

public class GI3ASPDOTNETMVCENTITYContext : DbContext { 
    public GI3ASPDOTNETMVCENTITYContext() : base("name=GI3ASPDOTNETMVCENTITYContext"){} 
    public System.Data.Entity.DbSet<GI3ASPDOTNETMVCENTITY.Models.Student> Students { get; set; } 
    public System.Data.Entity.DbSet<GI3ASPDOTNETMVCENTITY.Models.Professor> Professors { get; set; } 
    public System.Data.Entity.DbSet<GI3ASPDOTNETMVCENTITY.Models.Module> Modules { get; set; } 
    public System.Data.Entity.DbSet<GI3ASPDOTNETMVCENTITY.Models.Element> Elements { get; set; } 
    protected override void OnModelCreating(DbModelBuilder modelBuilder){ 
     base.OnModelCreating(modelBuilder); 
     modelBuilder.Entity<Module>().HasOptional(m => m.ResponsibleProfessor).WithMany(p => p.Modules).HasForeignKey(m => m.ProfessorID).WillCascadeOnDelete(false); 
     modelBuilder.Entity<Element>().HasRequired(e => e.Module).WithMany(m => m.ModuleElements).HasForeignKey(e => e.ModuleID).WillCascadeOnDelete(true); 
     modelBuilder.Entity<Element>().HasOptional(e => e.Professor).WithMany(p => p.Elements).HasForeignKey(e => e.ProfessorID).WillCascadeOnDelete(false); 
     modelBuilder.Entity<Professor>().HasMany(p => p.Elements).WithOptional(e => e.Professor).WillCascadeOnDelete(false); 
     modelBuilder.Entity<Professor>().HasMany(p => p.Modules).WithOptional(m => m.ResponsibleProfessor).WillCascadeOnDelete(false); 
    }  
} 

试图删除教授条目时我已经播种了数据库的样本数据,因此,它停止说:


DELETE语句与REFERENCE约束“FK_dbo.Elements_dbo.Professors_ProfessorID”冲突。冲突发生在数据库“GI3_1”,表“dbo.Elements”,列'ProfessorID'。 该声明已被终止。

描述: 当前Web请求执行过程中发生了未处理的异常。请查看堆栈跟踪以获取有关该错误的更多信息以及源代码的位置。

异常详细信息:System.Data.SqlClient.SqlException:在DELETE语句 冲突与基准约束 “FK_dbo.Elements_dbo.Professors_ProfessorID”。冲突发生在 数据库“GI3_1”,表“dbo.Elements”,列'ProfessorID'。 声明已被终止。

线113:教授教授= db.Professors.Find(ID); 114行:db.Professors.Remove(教授);第115行:
db.SaveChanges();第116行:return RedirectToAction(“Index”);第117行:}

回答

1

这取决于您在教授删除时想要发生什么。在你的情况下,我想它必须从相关的模块和元素取消分配(而不是删除它们)。

不幸的是,因为你不能打开级联操作,你必须这样做手工:

Professor toBeDeleted = ...; 
foreach (var module in db.Modules.Where(m => m.ProfessorID == toBeDeleted.ProfessorID)) 
    module.ProfessorID = null; 
foreach (var element in db.Elements.Where(e => e.ProfessorID == toBeDeleted.ProfessorID)) 
    element.ProfessorID = null; 
db.Professors.Remove(toBeDeleted); 
db.SaveChanges();