无法在对象中插入重复的键(GetReparentedValue/hierarchyid)
使用我在网上找到的示例,我创建了一个函数,该函数使用 GetReparentedValue 重新设置子级的父级。
但是,当我运行代码时,出现以下错误:无法在对象中插入重复的键。
我明白为什么(因为我试图重新设置孩子的父级,而新的父级已经有了孩子,所以我需要知道新父级结构中子级的最大路径(hierarchyid),但我不明白我实际上是如何 我必须在添加子项时执行
路径 0x58
oldPath 0x
新路径 0x68
SqlCommand command = new SqlCommand("UPDATE Structure SET " +
"Path = " + path + ".GetReparentedValue" +
"(" +
oldPath + ", " + newPath +
")" +
"ParentID = @id " +
"WHERE Path = " + path, _connection);
此操作,因此我认为需要将其添加到上面的查询中,但我不知道路径 + ".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
有人有任何建议吗?
提前感谢您的帮助:-)
Clare
Using examples I found on the web I have created a function which reparents children using the GetReparentedValue.
However when I have ran the code I get the following error: Cannot insert duplicate key in object.
I understand why (because I am trying to reparent the children and the new parent already has children so I need to know the MAX path (hierarchyid) of the child within the new parent structure, but I don't understand how I'm actually going to do that.
path 0x58
oldPath 0x
new path 0x68
SqlCommand command = new SqlCommand("UPDATE Structure SET " +
"Path = " + path + ".GetReparentedValue" +
"(" +
oldPath + ", " + newPath +
")" +
"ParentID = @id " +
"WHERE Path = " + path, _connection);
I have to do this when adding a child so I thought it would need to add this somewhere to the query above but I dont know where path + ".GetDescendant(" + lastChildPath + ", NULL)
Database Table
StructureID int Unchecked
Path hierarchyid Unchecked
PathLevel ([Path].[GetLevel]()) Checked
Description nvarchar(50) Checked
ParentID int Checked
ParentPath ([Path].[GetAncestor]((1))) Checked
Anyone have any suggestion?
Thanks in advance for any help :-)
Clare
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以进行一些更改来使其发挥作用。首先,您不需要表示要移动的节点的父节点的
oldPath
。在.GetReparentedValue
函数中,输入正在移动的节点的hierarchyid,即path
中的值。第二个更改是添加另一个 SELECT 语句来应用您的
GetDescendant
函数。下面是一个示例脚本,您可以在 SQL Server Management Studio (SSMS) 中尝试该脚本,也可以对其进行更改以合并到 SQLCommand 调用中。前几行(变量声明是赋值)仅用于在 SSMS 中运行。您可以将最后的SELECT
和UPDATE
语句传输到调用代码。您的
UPDATE
语句和此修订版只会重新指定单个节点的父级。它不会自动移动移动节点的子节点。移动节点的子节点将成为孤儿。如果需要移动所选节点及其所有后代,可以使用前面语句的以下变体。
实际上,从第一个脚本到此脚本的唯一更改是在最后一行。
Path.IsDescendantOf(@Path) = 1
测试对于@Path
的所有后代(包括@Path
)均成立。更新后仍将保留层级关系。There are a couple of changes you can make to get this to work. First, you don't need the
oldPath
that represents the parent of the node that you want to move. In the.GetReparentedValue
function, you put the hierarchyid of the node that is moving, which is the value inpath
.The second change is to add another SELECT statement to apply your
GetDescendant
function. Here's a sample script that you can try in SQL Server Management Studio (SSMS), or alter to incorporate into your SQLCommand calls. The first few lines (variable declarations are assignments) are only for running in SSMS. You would transfer the lastSELECT
and theUPDATE
statements to the calling code.Your
UPDATE
statement and this revision will only re-parent a single node. It will not automatically move the children of the moving node. Children of the moving-node will be orphaned.If you need to move the selected node and all descendants of the node, you can use the following variation of the previous statements.
Actually, the only change from the first script to this script is in the very last line. The
Path.IsDescendantOf(@Path) = 1
test is true for all descendants of@Path
, including@Path
. The hierarchical relationships will be maintained after the update.这是移动子树及其所有子树的另一个示例。它本质上与接受的答案相同。这取自 文档:
This is another example of moving a subtree and all of it's children. It is essentially the same as the accepted answer. This is taken from the Docs: