使用Save_Changes实体框架外键违规
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Save_Changes实体框架外键违规相关的知识,希望对你有一定的参考价值。
这绕过了令人愉快的场景,其中Entity Framework拒绝允许程序员改变保存数据的顺序......
结束结果:当我尝试保存我的更改(提交到SQLCE DB)时,我收到一个内部异常的错误:“无法插入外键值,因为不存在相应的主键值。[Foreign键约束名称=]“
为什么会发生这种情况:我有一部分VB.Net程序允许用户与驻留在内存中的数据进行交互。就用户而言,它看起来和感觉就像是在与数据库进行交互。完成本节中的工作后,他们可以保存/应用更改或取消更改。我选择这条路线是为了最简单的“退出”并减少了与DB的交互(我不想在用户更改内容时对DB进行不必要的插入/更新/删除)。
通过取消,我只需使用Context Refresh方法从DB重新加载EF数据,从而消除他们所做的任何事情。通过保存/应用,我只需调用上下文的“Save_Changes”方法即可一劳永逸地提交当前信息。 DB是本地SQLCE,只有具有单个用户的应用程序才能访问它。我不关心多个连接导致信息的并发问题。
这里的问题是,我有3个表,每个表都有一对多的层次关系:TableA 1 - > * TableB 1 - > * TableC
发生的事情是EF试图首先将DB中的更改保存到TableC而不是TableA,依此类推。嗯......那种使得DB中的FK约束不高兴,因为DB约束(EF已被设置为匹配),抱怨表格中保存的条目不能存在,因为表B中引用的条目键不存在还没存在.....实体框架很高兴,因为所有这些约束都在内存中的EF模型中得到满足,但它并没有以正确的顺序将它们提交给数据库,因此违规。
我正在使用Visual Studio 2010 Express(限制我使用SQLCE 3.5)和.net 4.我已经运行了VSE 2010的所有当前Service Pack,据我所知,我正在运行此设置允许的最新版本的EF因为我的项目参考仍然显示.net 4.0.0.0。我尝试实施EF 5,但它似乎不适用于VSE 2010。
我是否只需要从数据库中删除约束并仅在实体框架模型中使用它们?我真的不喜欢这个选项,但是如果这个EF版本有一个错误,它按照错误的顺序按照错误的顺序提交给DB,那么我想在VSE 2012发布之前我没有多少选择....
编辑:这是负责填充内存中的表的代码。正在读取的文件具有顺序,因此如果没有添加父项,则不会找到子条目。
Dim lines() As String = IO.File.ReadAllLines(dlgOpen.FileName)
For Each line In lines
'Remove surrounding whitespaces
line = Trim(line)
'Identify if line is MIB, Class or an Attribute
If InStr(line, "MIB:", CompareMethod.Text) > 0 Then 'Found MIB entry
'Create new entry in the OID_MIB table
newMIB = SEDB.OID_MIB.CreateObject
curMIB = Guid.NewGuid
newMIB.M_ID = curMIB
newMIB.Name = Split_Line(line, 3)
newMIB.Description = ""
SEDB.OID_MIB.AddObject(newMIB)
MIBCount = MIBCount + 1
ElseIf InStr(line, "Class", CompareMethod.Text) = 1 Then
'Found Class entry
'Create new entry in the OID_Class table
newClass = SEDB.OID_Class.CreateObject
newClass.M_ID = curMIB
newClass.Name = Split_Line(line, 3)
newClass.OID = Split_Line(line, 2)
newClass.Description = ""
newClass.Tip = ""
SEDB.OID_Class.AddObject(newClass)
ClassCount = ClassCount + 1
ElseIf InStr(line, "attribute", CompareMethod.Text) = 1 Then
'Found Attribute entry
'Create new entry in the OID_Attribute table
newAttribute = SEDB.OID_Attribute.CreateObject
newAttribute.OID = Split_Line(line, 2)
newAttribute.C_OID = Get_ClassOID(newAttribute.OID)
newAttribute.Name = Split_Line(line, 3)
newAttribute.Description = ""
newAttribute.Tip = ""
newAttribute.Type = ""
SEDB.OID_Attribute.AddObject(newAttribute)
AttributeCount = AttributeCount + 1
End If
Next
我会在概念模型和数据库中确认正确设置我的约束,但是我没有足够的声望点来发布图片。
答:好吧我会......在做了一些修补之后,我只删除了DB侧的约束,只有TableC和TableB,如果这确实是一个“订单”问题,那么它仍然会被打破,只是具有从TableB到TableA的约束;然而,它并没有“破裂。
遍历数据库中保存的数据允许我识别来自文本文件的两个条目,其中将在属性表(TableC)中创建一个条目,该条目在类表(tableB)中没有相应的值。因此,FK违规。
奇怪的是,这是在导入过程中不会导致违规的原因。
无论如何,我知道问题出在数据源中,我将添加逻辑来解决这个问题。如Dabblernl所述,问题不在于保存时的EF订单。
非常感谢大家的耐心等待。
以上是关于使用Save_Changes实体框架外键违规的主要内容,如果未能解决你的问题,请参考以下文章