如何在Entity框架代码第一个数据库中删除相关对象?

时间:2012-07-25 16:29:24

标签: c# entity-framework code-first

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策略来创建数据库。如何强制实体框架删除此类相关数据???

3 个答案:

答案 0 :(得分:6)

答案 1 :(得分:3)

我有完全相同的问题,我最近想出了如何修复它,所以我想我只是添加到Dima提供的答案。

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

经过一番挖掘,我发现我必须在子类中建立一个外键关联,以便Entity Framework正确地进行级联删除。因此,您需要将代码更改为:

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

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

答案 2 :(得分:0)

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

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