首页 文章

INSERT语句与EF Core中的FOREIGN KEY约束冲突

提问于
浏览
0

关于这个错误的背景有很多问题,到目前为止我一直无法找到适用于我的情况的问题 .

我有很多关系,我试图用第3个表 Build . 它基本上是经理人协会的人 . 所有经理都是人,但不是所有人都是经理,每个人都有很多经理,每个经理都有很多人 . 因此在经理的表中是PersonIds . 在编辑中的人员控制器是将人与经理相关联的选项 . 单击可用的管理器并单击“保存”时,出现错误:

INSERT语句与FOREIGN KEY约束“FK_dbo.ManagerToEngineer_dbo.Manager_ManagerId”冲突 . 冲突发生在数据库“PROJECTNAME_16ce3f6a2a6c4ff0b1ce147d126984ba”,表“dbo.Manager”,列'ManagerId'中 . 该语句已终止 .

SaveChanges方法导致此错误:

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(PersonViewModel person)
        {
            if (ModelState.IsValid)
            {
                //var MyPerson = db.people.Find(person.PersonId);
                //MyPerson.FirstName = person.FirstName;
                //MyPerson.LastName = person.LastName;
                foreach (var item in db.ManagersToEngineers)
                {
                    if (item.EngineerId == person.PersonId)
                    {
                        db.Entry(item).State = EntityState.Deleted;
                    }
                }

                foreach (var item in person.EngineerManagers)
                {
                    if (item.Checked)
                    {
                        db.ManagersToEngineers.Add(new ManagerToEngineer() { EngineerId = person.PersonId, ManagerId = item.Id });
                    }
                }
                //db.Entry(person).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(person);
        }

相关型号:

public class ManagerToEngineer
    {
        [Key]
        public int ManagerToEngineerId { get; set; }

        [Required]
        [ForeignKey("engineer")]
        public int EngineerId { get; set; }

        [Required]
        [ForeignKey("manager")]
        public int ManagerId { get; set; }

        public virtual Person engineer { get; set; }
        public virtual Manager manager { get; set; }

    }

public class Manager
{
    [Key]
    public int ManagerId { get; set; }

    [Required]
    [ForeignKey("person")]
    public int EngineerId { get; set; }

    public virtual Person person { get; set; }
    public ICollection<ManagerToEngineer> ManagersToEngineers { get; set; }
}

public class PersonViewModel
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [Display(Name = "Managers")]
    public List<CheckBoxViewModel> EngineerManagers { get; set; }
}

public class CheckBoxViewModel
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public bool Checked { get; set; }
}

2 回答

  • 0

    您在ManagersToEngineer上有一个FK约束,因此在管理ManagersToEngineer之前,确保在外表上引用的项目工程师和经理(在您的情况下,管理员)是有效的 .

    更具体地说,item.Id是否存在于Manager表中?

  • 0

    首先,您应该重新考虑您的模型 . 词组:

    所有经理都是人,但不是所有人都是经理

    不会转化为多对多的关系 . 一个学生有很多课程,一个课程有很多学生是多对多的关系 . 你的情况更好地转化为:每个经理 is a 暗示继承而不是对象组成的人 . 但是,为了学习目的,让我们继续你的例子 .

    下面的代码(我改变了一点命名,请不要互换使用工程师和人,因为它增加了混乱):

    public class Person
    {
        public Person()
        {
            Managers = new HashSet<Manager>();
        }
    
        [Key]
        public int PersonId { get; set; }
    
        public string Name { get; set; }
    
        public virtual ICollection<Manager> Managers { get; set; }
    }
    
    public class Manager
    {
        public Manager()
        {
            Persons = new HashSet<Person>();
        }
    
        [Key]
        public int ManagerId { get; set; }
    
        public virtual ICollection<Person> Persons { get; set; }
    }
    
    public class CompanyContext : DbContext
    {
        public DbSet<Person> Persons { get; set; }
    
        public DbSet<Manager> Managers { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Person>()
               .HasMany(p => p.Managers).WithMany(m => m.Persons)
               .Map(t => t.MapLeftKey("PersonID")
                   .MapRightKey("ManagerID")
                   .ToTable("PersonToManager"));
        }
    }
    

    执行插入时,您会注意到 this is not a good design 的原因:

    static void Main(string[] args)
        {
            using (var db = new CompanyContext())
            {
                // add a person
                var person = new Person() { Name = "Joe" };
                db.Persons.Add(person);
    
                // "make" him manager
                var manager = new Manager();
                manager.Persons.Add(person);
                db.Managers.Add(manager);
    
                db.SaveChanges();
            }
    
            Console.ReadKey();
        }
    

    上面的代码编译并且应该运行(但是我无法测试它,因为我需要为关联表显式创建一个类,如果你的modelBuilder具有正确的定义,Entity Framework可以自己推导出它 .

    Please remember that the above code is only an example of a many-to-many relationship and not an actually good database design ,但我还是发布了它,而不仅仅是给你一个链接,看看你的代码和我的代码之间的区别 . 请按照教程here进行更好的理解,如果这是一个旨在(在某些时候)不仅仅是学习练习的项目,请阅读有关数据库设计如何转换为代码的一些教程(例如,如何在SQL中设计继承关系) ) .

相关问题