2010-08-25 36 views
4

使用我在网络上找到的示例我创建了一个使用GetReparentedValue来修正儿童的函数。无法在对象中插入重复键(GetReparentedValue/hierarchyid)

但是,当我运行代码时出现以下错误:无法在对象中插入重复键。

我明白为什么(因为我试图重新抚养孩子,而且新父母已经有孩子,所以我需要知道新父母结构中孩子的MAX路径(hierarchyid),但我不明白实际上,我打算这样做。

路径将0x58

oldPath 0X

新路径0x68

SqlCommand command = new SqlCommand("UPDATE Structure SET " + 
            "Path = " + path + ".GetReparentedValue" + 
            "(" + 
             oldPath + ", " + newPath + 
            ")" + 
            "ParentID = @id " + 
            "WHERE Path = " + path, _connection); 

我要为此添加一个孩子的时候,所以我认为这将需要在某个地方,添加到上面的查询,但我不知道在哪里path + ".GetDescendant(" + lastChildPath + ", NULL)

数据库表

StructureID int       Unchecked 
Path   hierarchyid     Unchecked 
PathLevel  ([Path].[GetLevel]())  Checked 
Description nvarchar(50)    Checked 
ParentID  int       Checked 
ParentPath ([Path].[GetAncestor]((1))) Checked 

任何人有什么建议吗?

在此先感谢您的帮助:-)

克莱尔

+0

你能展示你的餐桌是什么样的吗? – 2010-08-25 18:03:51

+0

罗纳德你好,我添加了表格 – ClareBear 2010-08-26 07:12:17

回答

2

有一对夫妇就可以使得到这个工作的变化。首先,您不需要表示要移动的节点的父节点的oldPath。在.GetReparentedValue函数中,您放置正在移动的节点的hierarchyid,这是path中的值。

第二个变化是添加另一个SELECT语句来应用您的GetDescendant函数。下面是一个示例脚本,您可以在SQL Server Management Studio(SSMS)中尝试,或者更改以合并到您的SQLCommand调用中。前几行(变量声明是赋值)仅用于在SSMS中运行。您会将最后的SELECTUPDATE语句转移到调用代码。

DECLARE @Path hierarchyid 
DECLARE @oldPath hierarchyid 
DECLARE @newPath hierarchyid 
SELECT @Path=0x58, @oldPath=0x, @newPath=0x68 

SELECT @newPath = @newPath.GetDescendant(MAX(Path), NULL) 
FROM Structure 
WHERE path.GetAncestor(1)[email protected]; 

UPDATE Structure 
SET Path = Path.GetReparentedValue(@Path, @newPath) 
WHERE Path = @Path; 

UPDATE声明,本次修订将只重新父单个节点。它不会自动移动移动节点的子节点。移动节点的孩子将成为孤儿。

如果您需要移动选定节点和节点的所有后代,则可以使用前面的语句的以下变体。

DECLARE @Path hierarchyid 
DECLARE @oldPath hierarchyid 
DECLARE @newPath hierarchyid 
SELECT @Path=0x58, @oldPath=0x, @newPath=0x68 

SELECT @newPath = @newPath.GetDescendant(MAX(Path), NULL) 
FROM Structure 
WHERE Path.GetAncestor(1) = @newPath ; 

UPDATE Structure 
SET Path = Path.GetReparentedValue(@Path, @newPath) 
WHERE Path.IsDescendantOf(@Path) = 1; 

实际上,从第一个脚本到这个脚本的唯一变化就在最后一行。所有@Path后代的Path.IsDescendantOf(@Path) = 1测试均为真,包括@Path。更新后将保持分层关系。

相关问题