我正在使用EF6,并且我试图删除父级而不在调用remove之前的上下文请求中包含子级。我意识到这个问题已被问过几次,我试图实现各种版本的答案,但是在删除父项而不在上下文请求中包含子项时,我仍然会遇到外键约束问题。
父:
public class Weapon
{
public Weapon()
{
Dices = new List<Dice>();
}
public Guid Id {get;set;}
public List<Dice> Dices { get; set; }
}
子:
public class Dice
{
public Guid Id { get; set; }
public int Sides { get; set; }
public Guid WeaponId { get; set; }
public Weapon Weapon { get; set; }
}
骰子映射
// Relationships
this.HasRequired(_ => _.Weapon)
.WithMany(_ => _.Dices)
.HasForeignKey(_ => _.WeaponId)
.WillCascadeOnDelete(true);
如果我在不包含Dice的情况下从上下文中获取武器,则由于外键约束,删除将失败。但是,如果我包含骰子,那么武器上的删除就可以解决问题了。 IE
使用:
public async Task<IHttpActionResult> DeleteWeapon(Guid id)
{
Weapon weapon = await _dbContext.Weapons.Include(w=>w.Dices).SingleOrDefaultAsync(w => w.Id == id);
_dbContext.Weapons.Remove(weapon);
await _dbContext.SaveChangesAsync();
return Ok();
}
失败:
public async Task<IHttpActionResult> DeleteWeapon(Guid id)
{
Weapon weapon = await _dbContext.Weapons.SingleOrDefaultAsync(w => w.Id == id);
_dbContext.Weapons.Remove(weapon);
await _dbContext.SaveChangesAsync();
return Ok();
}
我真的更愿意不必包含一个对象的所有子节点来删除父节点,而我就是WillCascadeOnDelete标志的用途。
答案 0 :(得分:0)
通常,关系数据库内置了约束,不允许删除作为关系父级的条目。这是数据库试图阻止您在破坏它的行上进行查询。
我不确定您为什么要删除该行,但常见的解决方法是在您尝试从调用BOOLEAN
中删除的表中添加Active
列。只需将条目标记为FALSE
,并使引用数据库的代码进行任何必要的检查,或使用更强大的查询,而不是删除行本身。
如果您绝对需要删除该行,则需要打破相应的关系。如果您仍想保存该关系数据,则需要另外一个表或其他东西来存储它,此时它变得比我上面用Active
行给出的解决方案更复杂。