我正在使用vb.net 2013,Entity Framework 6和SQL Server 2008 R2。
我正在尝试从子实体中删除,但这不起作用。但是,如果我尝试直接从上下文中删除,这可以。
在我的数据库中,我有2个表Students
和Result
。
这是我的代码不起作用:
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
为什么我的第一段代码不起作用?
答案 0 :(得分:0)
我猜你通过从Students
添加一个名为Results
的不可为空的字段Results
来定义Students
和StudentId
之间的关系或类似的。当您从Remove
的父Student
集合执行Results
时,EF并未真正从上下文中删除已删除的Result
,EF只会删除它们之间的关系和集合StudentId
子项中的Result
值为null,但子项仍保留在上下文中。因此,你得到一个无法保存的孤儿,因为FK字段为空。
问题在于,您的关系在概念上是一种识别关系,这意味着您不能拥有不属于Result
的{{1}}。但EF认为你的关系不具备身份。
您有两种选择:
Student
添加到StudentId
的主键,使EF将该关系识别为识别关系。你将有一个复合键。这样,当您将子项从父项中的集合中删除时,EF将负责将子项从上下文中删除。Results
和Remove
。通常第二个选项是首选,因为在EF中处理复合键有点复杂。您可以编写一个方法来封装每次从context.Remove
删除Result
时应该组合在一起的两个操作。
有关识别关系here的更多信息。