使用Entity Framework Code First中的自引用多对多关系删除表中的行

时间:2014-11-15 23:19:26

标签: asp.net-mvc ef-code-first many-to-many entity-framework-6

我一直在摸不着头脑,读了很多帖子,但无法解决这个问题。

我有一张Person表(见下文)。该表中的实体可以包含儿童和父母,他们也在同一张桌子中。

public class Person
{
    public int ID { get; set; }
    public int Name { get; set; }
    public virtual ICollection<Person> Children { get; set; }
    public virtual ICollection<Person> Parents { get; set; }
}

DataContext中的我的模型构建器是这样的:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .HasMany(c => c.Children)
            .WithMany(p => p.Parents)
            .Map(m=>
                {
                    m.ToTable("ParentChild");
                    m.MapLeftKey("ParentID");
                    m.MapRightKey("ChildID");
                });
    }

这很好用,并自动创建一个名为ParentChild的表,其中包含ParentID和ChildID。

现在问题是,我想删除一个有孩子的人,但不删除孩子。所以我想我还需要删除ParentChild表中的相应行(自动生成),但不知道该怎么做。

注意:我还试图明确创建ParentChild表,但这不起作用,在进行添加迁移时被拒绝。

为了给你提供更多信息,这是我在尝试删除Person中的一行时得到的错误:

  

DELETE语句与REFERENCE约束冲突   &#34; FK_dbo.PersonPerson_dbo.Person_Person_ID&#34 ;.冲突发生了   在数据库&#34; MyDatabase&#34;,table&#34; dbo.ParentChild&#34;,column&#39; ParentID&#39;。

(顺便说一句,我不知道为什么它会谈论PersonPerson数据库,因为我给自动生成的关系数据库命名为ParentChild。但即使我没有给它命名,它也是不起作用。

最后一件事,这里是PersonController中的Remove()存根(我原来是由Scaffolding制作的):

public ActionResult Delete(int id)
    {
        try
        {
            Person person = db.Persons.Find(id);
            db.Persons.Remove(person);
            db.SaveChanges();
        }
        catch (RetryLimitExceededException dex)
        {
            return RedirectToAction("Delete", new { id = id, saveChangesError = true });
        }
        return RedirectToAction("Index");
    }

我希望有人可以帮助我!

提前感谢您的帮助和欢呼,

的Marius

1 个答案:

答案 0 :(得分:2)

好的,我终于弄明白了。

解决方案是修改PersonController中的Delete()存根,如下所示:

using (var context = new DataContext())
            {
                Person person= context.Persons.Find(id);

                foreach (var child in person.Children.ToList())
                {
                    person.Children.Remove(child);
                }

                foreach (var parent in person.Parents.ToList())
                {
                    person.Parents.Remove(parent);
                }

                context.Persons.Remove(patient);

                context.SaveChanges();
            }

这样,Delete()方法删除对父母和子女的引用,仅供参考。正如我在调用SaveChanges时一样,它避免了ForeignKey约束的麻烦!

希望这有助于某人。

干杯!