使用 EF 禁用级联删除?
Disable cascade delete with EF?
我有 2 个实体通过一对多关系链接如下(我首先使用代码):
public class Computer
{
[Key]
public int ComputerId { get; set; }
[Required]
public int ComputerIdInventory { get; set; }
[DataType(DataType.Date)]
public DateTime? AcquisitionDate { get; set; }
[DataType(DataType.Date)]
public DateTime? LastUpdate { get; set; }
public string Comment { get; set; }
//Foreign keys
public int? ComputerModelId { get; set; }
public int? EmployeeId { get; set; }
//Navigation properties
public virtual ICollection<Screen> Screens { get; set; }
}
public class Screen
{
[Key]
public int ScreenId { get; set; }
[Required]
public int ScreenIdInventory { get; set; }
public string Comment { get; set; }
//Foreign keys
public int? ComputerId { get; set; }
//Navigation properties
public virtual Computer Computer { get; set; }
}
当我删除链接到一个或多个屏幕的计算机时,出现以下错误:
[SqlException (0x80131904): The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.Screen_dbo.Computer_ComputerId". The conflict occurred in database "CPInventory", table "dbo.Screen", column 'ComputerId'.
我阅读了很多帖子,并且尝试了 2 件似乎对其他人有用的东西。我更改了 "OnModelCreating" 方法并添加了 :
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
我也试过了:
modelBuilder.Entity<Computer>()
.HasMany<Screen>(c => c.Screens)
.WithOptional(s => s.Computer)
.WillCascadeOnDelete(false);
但是 none 的解决方案有效...我做错了什么吗?我也更新了数据库,但没有任何改变。我是否必须完全删除我的数据库并重新创建它才能考虑这些更改?
非常感谢!
编辑:
这是删除代码
public ActionResult DeleteConfirmed(int id)
{
Computer computer = db.Computers.Find(id);
db.Computers.Remove(computer);
db.SaveChanges();
return RedirectToAction("Index");
}
问题是您在数据库中有一个外键约束,表示如果数据库中有子行(屏幕)则您不能删除父行(计算机)。
这就是你当初有级联删除功能的原因,所以删除电脑也就删除了屏幕。
您唯一的选择是在删除计算机之前删除具有相同 ComputerID 的所有屏幕。 (或者为什么不打开级联删除并让框架为您完成)
您无法删除屏幕上的 ComputerId
与计算机的 ComputerId
相匹配的计算机。
所以更新屏幕:
screen.ComputerId = null;
然后删除你的电脑
db.Set<Computer>().Remove(computer);
然后保存更改
db.SaveChanges();
我有 2 个实体通过一对多关系链接如下(我首先使用代码):
public class Computer
{
[Key]
public int ComputerId { get; set; }
[Required]
public int ComputerIdInventory { get; set; }
[DataType(DataType.Date)]
public DateTime? AcquisitionDate { get; set; }
[DataType(DataType.Date)]
public DateTime? LastUpdate { get; set; }
public string Comment { get; set; }
//Foreign keys
public int? ComputerModelId { get; set; }
public int? EmployeeId { get; set; }
//Navigation properties
public virtual ICollection<Screen> Screens { get; set; }
}
public class Screen
{
[Key]
public int ScreenId { get; set; }
[Required]
public int ScreenIdInventory { get; set; }
public string Comment { get; set; }
//Foreign keys
public int? ComputerId { get; set; }
//Navigation properties
public virtual Computer Computer { get; set; }
}
当我删除链接到一个或多个屏幕的计算机时,出现以下错误:
[SqlException (0x80131904): The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.Screen_dbo.Computer_ComputerId". The conflict occurred in database "CPInventory", table "dbo.Screen", column 'ComputerId'.
我阅读了很多帖子,并且尝试了 2 件似乎对其他人有用的东西。我更改了 "OnModelCreating" 方法并添加了 :
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
我也试过了:
modelBuilder.Entity<Computer>()
.HasMany<Screen>(c => c.Screens)
.WithOptional(s => s.Computer)
.WillCascadeOnDelete(false);
但是 none 的解决方案有效...我做错了什么吗?我也更新了数据库,但没有任何改变。我是否必须完全删除我的数据库并重新创建它才能考虑这些更改?
非常感谢!
编辑: 这是删除代码
public ActionResult DeleteConfirmed(int id)
{
Computer computer = db.Computers.Find(id);
db.Computers.Remove(computer);
db.SaveChanges();
return RedirectToAction("Index");
}
问题是您在数据库中有一个外键约束,表示如果数据库中有子行(屏幕)则您不能删除父行(计算机)。
这就是你当初有级联删除功能的原因,所以删除电脑也就删除了屏幕。
您唯一的选择是在删除计算机之前删除具有相同 ComputerID 的所有屏幕。 (或者为什么不打开级联删除并让框架为您完成)
您无法删除屏幕上的 ComputerId
与计算机的 ComputerId
相匹配的计算机。
所以更新屏幕:
screen.ComputerId = null;
然后删除你的电脑
db.Set<Computer>().Remove(computer);
然后保存更改
db.SaveChanges();