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

时间:2015-10-22 02:03:59

标签: c# .net sql-server recursion ado.net

使用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对象/ row和对象有25个属性映射到inhertance表层次结构中的25个列,那么使用c#ado.net将该对象插入表的最佳方法是什么?我可以在这使用cte吗?

1 个答案:

答案 0 :(得分:1)

这是一种方法。您可以尝试通过传递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;