使用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实体框架外键违规的主要内容,如果未能解决你的问题,请参考以下文章

JPA @SecondaryTable 外键违规

实体框架 4.1 代码优先外键 ID

理解实体框架核心外键关系

首次使用实体框架代码时将外键设置为 null

使用实体框架代码首先获得来自同一个父表的两个外键,而无需指定父实体上的集合

实体框架中与代码优先外键的更改冲突