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();
}
...
}
实体框架使用两个表创建数据库:Planets
和Buildings
,与Planet_Id
字段相关。当我调用RemovePlanets()
类的VGDBRepository
方法时,它会从行星表中删除行星记录,并将与已删除的行星相关的所有建筑物的Planet_Id
字段设置为null,但不删除它们,所以我在数据库中有冗余记录。我使用code-first
策略来创建数据库。如何强制实体框架删除此类相关数据???
答案 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);
}