在递归表中插入递归/嵌套对象

本文关键字:递归 嵌套 对象 插入 | 更新日期: 2023-09-27 18:18:41

使用microsoft sql server假设以下示例表具有递归关系

[dbo].[IPAddress]
(
    [IPAddressID] [int] PRIMARY KEY IDENTITY(1,1),
    [IP] [nchar] (15),
    [ParentID] [int] FOREIGN KEY REFERENCES [IPAddressID]
)

我有以下嵌套对象,它具有相同类型对象的列表

public class IPAddress
{
    public int IPAddressID { get; set; }
    public string IP { get; set; }
    public IPAddress[] Childs { get; set; }
}
var IP = new IPAddress
{
    IP = "10.0.0.0",
    Childs = new IPAddress[]
    {
        new IPAddress
        {
            IP="10.1.0.0",
            Childs = new IPAddress[]
            {
                new IPAddress{ IP="10.1.1.0" },
                new IPAddress{ IP="10.1.2.0" },
                new IPAddress{ IP="10.1.3.0" }
            }
        }
    }
};

当插入对象时,表数据应该是这样的:

IPAddressID,IP,ParentID
10,'10.0.0.0',Null
12,'10.1.0.0',10
13,'10.1.1.0',12
14,'10.1.2.0',12
15,'10.1.3.0',12

在我的实际情况中,基本对象可能有60个孩子作为第二级,每个孩子在第二级有4个孩子在第三级然后平面对象计数是1 + 60 +(60*4)= 2461对象/行和对象有25个属性映射到继承表层次结构的25列,所以什么是最好的方法来插入该对象到表使用c# ado.net?我可以用cte吗?

在递归表中插入递归/嵌套对象

有一种方法可以做到。你可以通过传递你的IPAddress对象来调用这个方法。如果想要提高效率,可以用所有查询构建一个插入字符串,并且只调用一次ExecuteNonQuery。注意,每个查询有1000个插入限制。

public void InsertIpAdress(IPAddress myipaddress)
{
string cs = "Put your connection string"
SqlConnection cn = new SqlConnection(cs);
try
{
    //Open connection
    cn.Open();
    //First we insert the parent(Use stored procedure provided if you want)
    SqlCommand cm = new SqlCommand("[dbo].[AddParent]", cn);
    cm.CommandType = CommandType.StoredProcedure;
    //Add parameter
    cm.Parameters.AddWithValue("@IP", myipaddress.IP);
    //Output parameter
    SqlParameter output = new SqlParameter("@Parent",SqlDbType.Int);
    output.Direction = ParameterDirection.Output;
    cm.Parameters.Add(output);
    //Execute query
    cm.ExecuteNonQuery();
    //Here we get parent id
    int parent = Convert.ToInt32(output.Value.ToString());
    //Then we have to add every children
    cm = new SqlCommand("INSERT INTO YourTable (IP,ParentID) VALUES (@ip,@parent);", cn);
    //Add parent as parameter 
    cm.Parameters.AddWithValue("@parent", parent);
    foreach(IPAddress element in myipaddress.Childs)
    {
        //Add the current child ip
        cm.Parameters.AddWithValue("@ip", element.IP);
        //Execute command
        cm.ExecuteNonQuery();
    }
    //Close connection
    cn.Close();
}
catch(Exception ex)
{
    //You can handle exceptions here
    MessageBox.Show(ex.message);
}
}

存储过程是这样的

ALTER PROCEDURE [dbo].[AddParent]
    @IP          NVARCHAR(50),
    @Parent      INT OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    INSERT INTO YourTable (IP,ParentID) VALUES (IP,null);
    SET @Parent = SCOPE_IDENTITY();
END;