将 C# 嵌套对象保存到 SQL 服务器的有效方法

本文关键字:服务器 有效 方法 SQL 嵌套 对象 保存 | 更新日期: 2023-09-27 18:21:55

>我有一个嵌套到 5 个级别的表结构,具有向下的一对多关系。我想知道将此类数据保存到 SQL Server 中的有效方法是什么。我现在循环每个子对象 (C#( 并运行一个插入,如果数据很大,它会变慢。

有没有办法在传统 ADO.NET 中将 C# 直接传递给 SQL?我有一个自定义框架,它为每个插入触发一个 SQL 脚本,该脚本从对象属性中获取值。我无法迁移到 EF 或 NHirbernate,因为它是一个现有项目。

我已经看到了可以将 C# 对象插入到数据表中然后传递给 SQl 的方法,这是一种有效的方法吗?

请指教。

将 C# 嵌套对象保存到 SQL 服务器的有效方法

我假设从数据库的角度来看你有这样的东西

CREATE TABLE Items (ID INT -- primary key, 
                    Name VARCHAR(MAX),
                    ParentID INT) -- foreign key that loops on the same table

以及 C# 中这样的对象

public class Item
{
   public int ID {get; set;}
   public string Name {get; set;}
   public int ParentID {get; set;}
   public Item Parent {get; set;}
   public List<Item> Children {get; set;}
}

你有一些代码,如下所示:

var root = MakeMeATree();
databaseSaver.SaveToDatabase(root);

这将为每个孩子生成每个项目的插入。如果您有很多孩子,这确实会减慢应用程序的速度。

在这种情况下,我将使用(并且已经使用(的是自定义sql服务器类型和存储过程,以在单个调用中保存整个内容。

您需要创建与表匹配的类型:

CREATE TYPE dbo.ItemType AS TABLE
(
    ID INT,
    Name VARCHAR(MAX),
    ParentID INT
);

以及使用该类型的简单过程:

CREATE PROCEDURE dbo.InsertItems
(
  @Items AS dbo.ItemType READONLY
)
AS
BEGIN
  INSERT INTO SampleTable(ID, Name, ParentID)
  SELECT ID, Name, ParentID From @Items
END

现在,这是从SQL Server端完成的。现在进入 C# 端。您需要做两件事:

  1. 将层次结构平展为列表
  2. 将该列表作为数据表发送到数据库

第一个可以使用这样的东西来完成(我使用这个,这基本上是相同的东西(,一个简单的

var items = root.Flatten(i => i.Children);

若要执行第二件事,首先需要将 SQL Server 类型声明为数据表:

DataTable dt = new DataTable("Items"); 
dt.Columns.Add("ID", typeof(int)); 
dt.Columns.Add("Name", typeof(string)); 
dt.Columns.Add("ParentID", typeof(int)); 

接下来,只需填写值:

foreach(var item in items)
{
   dt.Rows.Add(item.ID, item.Name, item.ParentID);
}

并将它们附加到 SqlParameter ,应该是 SqlDbType.Structured 类型,如下所示:

using (var cmd = new SqlCommand("InsertItems", connection))
{
    cmd.CommandType = CommandType.StoredProcedure;
    var itemsParam = new SqlParameter("@Items", SqlDbType.Structured);
    itemsParam .Value = dt;
    cmd.Parameters.Add(itemsParam);
    cmd.ExecuteNonQuery();
}

而且,应该就是这样。

是的,如果您希望将数据集对象存储在数据库中,则可以使用以下选项:创建一个 SQL 用户定义类型对象。填充对象所需的值,并在存储过程中读取值,并在 Temp 中填充对象值,并使用业务逻辑存储在 DB 中。