【问题标题】:Circular Reference Entity Framework Reference Constraint Fails when Deleting Professor Entry删除教授条目时循环引用实体框架引用约束失败
【发布时间】:2016-12-15 10:01:27
【问题描述】:

我遇到过循环引用不可避免的情况,我有三个模型类:教授、模块、元素:

  • 教授负责零个或多个模块
  • 一个模块有零个或一个教授负责
  • 一个模块可能包含多个元素或不包含元素
  • 每个元素由一位或零位教授教授

我的模型类:

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; }
}

我的数据库上下文:

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”列中发生冲突。 声明已终止。

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

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

第 113 行:教授professor = db.Professors.Find(id); 第 114 行:db.Professors.Remove(professor);第 115 行:
db.SaveChanges();第 116 行:返回 RedirectToAction("索引");第 117 行:}

【问题讨论】:

    标签: c# sql-server entity-framework ef-fluent-api


    【解决方案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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多