首页 > 解决方案 > 如何使用单个查询插入许多子/父项

问题描述

假设我们有以下 SQL Server 表结构:

MainItem
........
ID (int)
Total (money)

SubItem
........
ID (int)
MainItemID (int)
Price (money)

我们需要生成数千个 MainItem,每个 MainItem 有几十个 SubItem,并一次将其输入数据库。目前我们的代码看起来像这样:

Dictionary<int, int> oldToNewIDs = new Dictionary<int, int>();
foreach(MainItem mainItem in GeneratedMainItems)
{
    int oldID = mainItem.ID;
    mainItem.Update();
    oldToNewIDs.Add(oldID, mainItem.ID);
}
foreach (SubItem subItem in GeneratedSubItems)
{
    fi.MainItemID = oldToNewIDs[fi.MainItemID];
    subItemsToInsert.Add(fi);
}

InsertAllSubItemsAtOnce(subItemsToInsert);

一次插入所有子项的代码如下所示:

string sql = @"
INSERT INTO SubItems (MainItemID, Price) VALUES (1, 100)
INSERT INTO SubItems (MainItemID, Price) VALUES (1, 50)
INSERT INTO SubItems (MainItemID, Price) VALUES (2, 20)
...
";
UpdateDB(sql);

我们目前面临的问题是,有一次,只插入了一半的子项。所以我们最终得到了错误的总数和子项。我不完全明白这是怎么发生的,但我猜是 sql server 出了点问题?

我们想要实现的是,我们一次插入所有内容(主项和子项),如果出现问题,插入将被中止,因此我们不会得到无效数据。如何才能做到这一点?

标签: c#sql.netsql-server

解决方案


将您的工作量放入事务中

using (var conn = new SqlConnection(connStr))
{
    conn.Open();
    var cmd = new SqlCommand(sql , conn, conn.BeginTransaction());

    try
    {
        cmd.ExecuteNonQuery();
        cmd.Transaction.Commit();
    }
    catch(System.Exception ex)
    {
        cmd.Transaction.Rollback();
        throw ex;
    }

    conn.Close();
}

推荐阅读