C# 如何删除实体框架代码优先数据库中的相关对象?

C# 如何删除实体框架代码优先数据库中的相关对象?,c#,entity-framework,code-first,C#,Entity Framework,Code First,DBContext类是 public class VGDB : DbContext { public DbSet<Planet> Planets { get; set; } } 实体框架使用两个表创建数据库:行星和建筑物,由行星Id字段关联。当我调用我的VGDBRepository类的RemovePlanets()方法时,它会从planets表中删除planets记录,并将buildings表中与已删除的行星相关的所有建筑物的Plan

DBContext类是

public class VGDB : DbContext
    {        
        public DbSet<Planet> Planets { get; set; }
    }

实体框架使用两个表创建数据库:
行星
建筑物
,由
行星Id
字段关联。当我调用我的
VGDBRepository
类的
RemovePlanets()
方法时,它会从planets表中删除planets记录,并将buildings表中与已删除的行星相关的所有建筑物的
Planet_Id
字段设置为null,但不会删除它们,所以我在数据库中有冗余记录。我使用
code-first
策略创建数据库。如何强制实体框架删除此类相关数据?

您需要级联删除

看看这个:

这是:

我遇到了完全相同的问题,最近我找到了解决方法,所以我想我应该补充一下Dima提供的答案

你们上面关于行星和建筑的代码看起来和我设置相关物体的方式非常相似;对我来说,建立这样的关系是有道理的。此外,通过FK引用返回父表,这些表似乎可以正确生成。和你一样,当我删除我的父记录(在你的例子中是行星)时,子记录(在你的例子中是建筑物)仍然保留着,但是FK字段删除了父ID,因此它只有一个空值。不过,这些对象已从内存中的集合中删除,因此事情变得不同步。让我感到困惑的是,实体框架代码首先应该,默认情况下,像这样级联删除,我不明白为什么我的删除不是级联的

在深入研究之后,我发现我必须在子类中建立外键关联,以便实体框架正确地执行级联删除。因此,您需要将代码更改为如下所示:

    public class Planet
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }

    ...

    public List<Building> Constructions { get; set; } 
}


public class Building
{
    [Key]
    public int Id { get; set; }
    public decimal Lvl { get; set; }
    public string Type { get; set; }
    //Add these two properties to create the Foreign Key Association
    public int planetID { get; set; }
    public Planet planet { get; set; }
}
公共级行星
{
[关键]
公共int Id{get;set;}
公共字符串名称{get;set;}
...
公共列表结构{get;set;}
}
公共班级大楼
{
[关键]
公共int Id{get;set;}
公共十进制Lvl{get;set;}
公共字符串类型{get;set;}
//添加这两个属性以创建外键关联
公共int planetID{get;set;}
公共行星{get;set;}
}

当我添加这两个属性并在数据库上执行自动迁移时,删除就像我预期的那样层叠而来。我仍然有点不清楚为什么需要这样做,但这是一个单独的帖子主题。。。我只是想和大家分享一下,是什么让这本书对我有用。

急切的加载可能会对你有所帮助。否则,启用延迟加载

 foreach (Planet planet in _vgdb.Planets)
        {
            _vgdb.Planets.Include(p=>p.Constructions).Remove(planet);
        }

如果我真的想像上面那样做,我不想删除父对象,只删除子对象。entity.childCollection.clear();db.SaveChanges()似乎不起作用:(@Wardy,您只需删除子项而不对父项进行任何更改。
foreach(parent.children中的var child)db.ChildDbSet.remove(child);
…或者我认为必须为db set提供RemoveRange方法…
db.ChildDbSet.RemoveRange(parent.children)
ah thx…知道我遗漏了一些简单的东西
    public class Planet
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }

    ...

    public List<Building> Constructions { get; set; } 
}


public class Building
{
    [Key]
    public int Id { get; set; }
    public decimal Lvl { get; set; }
    public string Type { get; set; }
    //Add these two properties to create the Foreign Key Association
    public int planetID { get; set; }
    public Planet planet { get; set; }
}
 foreach (Planet planet in _vgdb.Planets)
        {
            _vgdb.Planets.Include(p=>p.Constructions).Remove(planet);
        }