4

DBContext 类是

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

模型看起来像:

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

存储库类:

public class VGDBRepository
    {
        private readonly VGDB _vgdb;
        ...
        public void RemovePlanets()
        {
            foreach (Planet planet in _vgdb.Planets)
            {
                _vgdb.Planets.Remove(planet);
            }
            _vgdb.SaveChanges();
        }
        ...
    }

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

4

3 回答 3

6

您需要级联删除。

看看这个: Stackoverflow 示例级联删除

还有这个: Msdn Code First with Enable Cascade Deletes

于 2012-07-25T16:35:24.990 回答
3

我遇到了完全相同的问题,我最近想出了如何解决它,所以我想我只是补充一下 Dima 提供的答案。

上面的 Planet 和 Building 代码看起来与我设置相关对象的方式非常相似;建立这样的关系对我来说很有意义。此外,这些表似乎通过 FK 引用正确生成回父表。像您一样,当我删除父记录(在您的情况下为行星)时,子记录(在您的情况下为建筑物)仍然存在,但 FK 字段已删除父 ID,因此它只有一个空值。但是,这些对象已从内存集合中删除,因此事情变得不同步。让我真正感到困惑的是,Entity Framework Code First 应该在默认情况下像这样级联删除,我不明白为什么我的删除没有级联。

经过一番挖掘,我发现我必须在子类中设置一个外键关联,以便实体框架正确地进行级联删除。因此,您需要将代码更改为如下所示:

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

一旦我添加了这两个属性并在我的数据库上进行了自动迁移,删除就像我预期的那样级联。我仍然有点不清楚为什么需要这样做,但这是一个单独的帖子的主题......我只是想我会分享让这对我有用的东西。

于 2012-08-15T08:37:11.633 回答
0

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

 foreach (Planet planet in _vgdb.Planets)
        {
            _vgdb.Planets.Include(p=>p.Constructions).Remove(planet);
        }
于 2017-08-29T13:16:01.050 回答