0

好吧,我正在尝试将一棵树保存在数据库中,因此我使用了修改后的预排序树遍历方法。

我有一个包含以下列的表格:

IDNode
IDRootNode
IDParentNode
Left
Right

在我的表中,我有两个唯一的约束,(IDRoot, Left)因为(IDRoot, right)在树中,不可能有两个节点具有相同的根和相同的左边,或者相同的根和相同的右边。这就是使用这两个约束的原因。

好吧,现在,我有一个包含三个节点的树:

Node A
IDNode = 1
IDRootNode = 1
IDParentNode = 1
Left = 1
Right = 6

Node B
IDNode = 2
IDRootNode = 1
IDParentNode = 1
Left = 2
Right = 3

Node C
IDNode = 3
IDRootNode = 1
IDParentNode = 1
Left = 4
Right = 5

现在我正在尝试在 B 节点中添加一个新子节点。所以通过一些操作,在数据库中保存更改之前,我得到了节点的以下状态:

Node A
IDNode = 1
IDRootNode = 1
IDParentNode = 1
Left = 1
Right = 8

Node B
IDNode = 2
IDRootNode = 1
IDParentNode = 1
Left = 2
Right = 5

Node C
IDNode = 3
IDRootNode = 1
IDParentNode = 1
Left = 6
Right = 7


New node D
IDNode = 3
IDRootNode = 1
IDParentNode = 2
Left = 3
Right = 4

这是所有节点的正确数据,但是当我提交更改时,我得到一个唯一键异常,因为我正在尝试修改左/右值。

问题出在节点 B 上,我试图将正确的字段设置为 5,但是这个值被分配给数据库中的节点 C。

所以它让我觉得当 EF 进行更改时,它将更改应用于当前寄存器并将数据与数据库中的信息进行比较,而不是与上下文中实体的信息进行比较。因此,当我尝试更新节点 B 时,它不考虑实体值,而是考虑数据库中的值,所以在数据库中节点 C 的右侧字段中的值为 5 时,SQL Server 会抛出错误,因为的唯一约束。如果 EF 考虑实体数据,其中节点 C 的值为 7,则不会有问题。

如果我删除数据库中的约束,一切正常并且数据是一致的,但是我会根据EF的使用来设计数据库,并且设计将独立于数据访问技术。

我对吗?EF 是否可以在考虑其他实体的其他可能更改的情况下进行更改?

谢谢。戴姆洛克。

4

1 回答 1

1

您在示例中显示的内容看起来根本不像一棵树。让我们检查您修改后的示例:

  • 节点 A 的 ID = 1,RootID = 1 和 ParentID = 1。根节点如何有父节点?ParentID 应为 NULL。
  • 节点 A 的 LeftID = 1。所以它指向自己?那是什么树?即使在线程树节点中,通常也不指向自身。
  • 节点 B 的 ParentID = 1 但节点 A 既没有 LeftID = 2 也没有 RightID = 2。当节点 B 不是节点 A 的直接子节点时,节点 A 如何成为节点 B 的直接父节点?
  • 还有更多类似的问题
  • 顺便提一句。您如何使用您的唯一约束对叶子或不完整节点(LeftID = NULL 或 RightID = NULL 的节点)建模?这些约束说明只能有 LeftID = NULL 的单个节点和 RightID = NULL 的单个节点

现在到 EF 的问题。EF 不理解独特的约束。EF 也不会对数据库执行任何其他查询来检查状态。所有查询都由您执行(甚至延迟加载也由您的代码执行)。

您发现很可能是在数据库中执行的更新命令顺序不正确的问题,其中 EF 在更新节点 C 之前尝试更新节点 B。EF 更新的顺序由数据库中的关系驱动,但双向关系可能导致 EF 是无法选择正确的命令顺序。在这种情况下,它通常会引发异常,因此我怀疑您没有在具有自引用关系的表上建模树结构。在这种情况下,EF 将无法分配正确的命令顺序。

我希望在这种情况下,您将不得不手动编写更新来执行更新。

于 2012-05-26T14:07:08.347 回答