错误从其父对象中删除子对象

时间:2018-02-14 19:40:08

标签: vb.net entity-framework entity-framework-6

我正在使用vb.net 2013,Entity Framework 6和SQL Server 2008 R2。

我正在尝试从子实体中删除,但这不起作用。但是,如果我尝试直接从上下文中删除,这可以。

在我的数据库中,我有2个表StudentsResult

这是我的代码不起作用:

Dim context as Myentities = New myentities.
Dim s as student.
Dim lresult as new list (of result)

s = context.students.where(Function(t1) t1.value>5).Tolist.first

lresult = (from t in s.results where t.vl2=7 select t).Tolist

for each rs as result in lresult
   if rs.vl3=11 then s.results.remove(rs)
Next

Context.SaveChanges

此代码在最后一行(context.SaveChanges)产生错误:

  

EntityFramework.dll中发生未处理的“System.InvalidOperationException”类型异常   附加信息:操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

但是,如果我更改删除项目的行,如下所示,则可以:

Dim context as Myentities = New myentities.
Dim s as student.
Dim lresult as new list (of result)

s = context.students.where(Function(t1) t1.value>5).Tolist.first
lresult = (from t in s.results where t.vl2=7 select t).Tolist

for each rs as result in lresult
   if rs.vl3=11 then context.results.remove(rs)
Next

Context.SaveChanges

为什么我的第一段代码不起作用?

1 个答案:

答案 0 :(得分:0)

我猜你通过从Students添加一个名为Results的不可为空的字段Results来定义StudentsStudentId之间的关系或类似的。当您从Remove的父Student集合执行Results时,EF并未真正从上下文中删除已删除的Result,EF只会删除它们之间的关系和集合StudentId子项中的Result值为null,但子项仍保留在上下文中。因此,你得到一个无法保存的孤儿,因为FK字段为空。

问题在于,您的关系在概念上是一种识别关系,这意味着您不能拥有不属于Result的{​​{1}}。但EF认为你的关系不具备身份。

您有两种选择:

  • 通过将外键字段Student添加到StudentId的主键,使EF将该关系识别为识别关系。你将有一个复合键。这样,当您将子项从父项中的集合中删除时,EF将负责将子项从上下文中删除。
  • 保留PK原样,并在保存之前从上下文中明确删除子项。也就是说,您同时执行父集合中的ResultsRemove

通常第二个选项是首选,因为在EF中处理复合键有点复杂。您可以编写一个方法来封装每次从context.Remove删除Result时应该组合在一起的两个操作。

有关识别关系here的更多信息。