如何将 objects (Parent-Child) 层次结构的 .NET Collection 传递给 SQL 服务器存储过程

How to pass .NET Collection of objects (Parent-Child) hierarchy to a SQL Server stored procedure

我需要将 .NET Collection 传递给存储过程。我的 collection 包含 1000 条记录。每条记录包含 2-3 child objects 个其他类型。

我需要通过从 .NET 调用存储过程来立即插入它们。

我已经尝试过 TVP(table-valued 参数),但这根本无法满足我的需求。

对于每个根级别记录,我需要通过传递根记录及其对应的 child 记录来调用存储过程。这使得整个过程非常缓慢。

这就是我寻找方法的原因,这样我就可以一次传递整个层次列表,在存储过程中,通过循环和迭代 child 记录,我可以插入 parent child记录。

我怎样才能做到这一点?

实际上我 3 周前刚做过这个。

  1. 创建一个 "temp" 关联键(我使用了 GUID)以 link parent 和 children 在一起,因为你没有数据库 ID(临时密钥永远不会保存在数据库中)
  2. 调用 TVP 存储过程。在两个单独的 table vars
  3. 中传递所有 parents 和所有 childred
  4. 创建一个临时 table 或 table 变量来存储 tempid/database id 关系
  5. 使用带有 OUTPUT 的合并语句将 Inserted.Id 值和临时 ID 放入在步骤 3table 中创建的临时
  6. 使用 CTE 和合并语句使用 parent 记录中的实际数据库 ID 插入 child 记录

这里有几个 link 关于这个过程的 "real" 个例子:

merge parent and child SQL Server tables

您可以使用 XML 将记录及其子项传递给存储过程。例如

DECLARE @xml XML = '<root>
<parent value="213">
    <child childValue="1111"></child>
    <child childValue="1112"></child>
</parent>
<parent value="2313">
    <child childValue="3333"></child>
    <child childValue="3332"></child>
</parent>
</root>'

然后你可以做很多方法,其中之一是对记录进行非规范化并保存到临时table以供进一步处理

    SELECT
    T.c.value('parent::*/@value', 'INT') AS ParentValue,
    T.c.value('@childValue', 'INT') AS ChildValue
    FROM @xml.nodes('/root[1]/parent/child') T(c)

结果会像

    ParentValue  ChildValue
    213          1111
    213          1112
    2313         3332
    2313         3333