2

这绕过了 Entity Framework 拒绝让程序员能够更改数据保存顺序的令人愉快的场景......

最终结果:当我尝试保存我的更改(提交到 SQLCE DB)时,我收到一个内部异常的错误:“无法插入外键值,因为相应的主键值不存在。[外键值键约束名称 = ]"

为什么会这样:我的 VB.Net 程序有一部分允许用户与内存中的数据进行交互。就他们的用户而言,它看起来和感觉就像他们正在与数据库进行交互。完成本节中的工作后,他们可以保存/应用更改或取消更改。我选择这条路线是为了最简单的“退出”并减少与数据库的交互(我不想在用户更改内容时对数据库进行不必要的插入/更新/删除)。

通过取消,我只需使用 Context Refresh 方法从 DB 重新加载 EF 数据,从而消除他们所做的任何事情。通过保存/应用,我只需调用上下文的“Save_Changes”方法来一劳永逸地提交当前信息。该数据库是一个本地 SQLCE,只有一个用户的应用程序正在访问它。我不担心多个连接会导致信息并发问题。

这里的问题是我有 3 个表,每个表都有一对多的层次关系: TableA 1->* TableB 1->* TableC

正在发生的事情是 EF 试图首先将 DB 中的更改保存到 TableC 而不是 TableA,依此类推。嗯.....那种让数据库中的FK约束不开心,因为数据库约束(EF已经设置为匹配)抱怨表C中保存的条目不能存在,因为表B中引用的条目键不存在不存在……还没有。Entity Framework 很高兴,因为所有这些约束都在内存中的 EF 模型中得到满足,但它没有以正确的顺序将它们提交给 DB,因此违反了。

我正在使用 Visual Studio 2010 Express(它限制我使用 SQLCE 3.5)和 .net 4。我已经为 VSE 2010 运行了所有当前的 Service Pack,据我所知,我正在运行此设置允许的最新版本的 EF因为我的项目参考仍然显示.net 4.0.0.0。我尝试实现 EF 5,但它似乎不适用于 VSE 2010。

我是否只需要从数据库中删除我的约束并仅在实体框架模型中使用它们?我真的不喜欢那个选项,但是如果这个 EF 版本有一个错误,它按照关系以错误的顺序提交到数据库,那么我想在 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

我会有一张图片来确认我在概念模型和数据库中的约束设置是否正确,但我还没有足够的声誉点来发布图片。

答:嗯,我会的……在做了一些修改之后,我删除了仅针对TableC和TableB的DB端的约束,如果这确实是一个“顺序”问题,那么它仍然会被破坏,只是具有从 TableB 到 TableA 的约束;然而,它并没有坏掉。

遍历数据库中保存的数据使我能够识别来自文本文件的两个条目,其中将在属性表​​ (TableC) 中创建一个条目,该条目在类表 (tableB) 中没有相应的值。因此,FK 违规。

奇怪的是,这在导入过程中如何没有造成违规。

无论如何,我知道问题出在数据源中,我会添加逻辑来解决这个问题。正如 Dabblernl 已经指出的那样,问题不在保存时的 EF 顺序中。

非常感谢大家的耐心等待。

4

1 回答 1

1

在做了一些修改之后,我删除了仅针对 TableC 和 TableB 的 DB 端的约束,如果这确实是一个“顺序”问题,那么它仍然会被破坏,只是从 TableB 到 TableA 的约束;然而,它并没有坏掉。

遍历数据库中保存的数据使我能够识别来自文本文件的两个条目,其中将在属性表​​ (TableC) 中创建一个条目,该条目在类表 (tableB) 中没有相应的值。因此,FK 违规。

奇怪的是,这在导入过程中如何没有造成违规。

无论如何,我知道问题出在数据源中,我会添加逻辑来解决这个问题。正如 Dabblernl 已经指出的那样,问题不在保存时的 EF 顺序中。

非常感谢大家的耐心等待。

于 2012-09-10T17:36:03.587 回答