ADO.NET - 更新多个数据表

Posted

技术标签:

【中文标题】ADO.NET - 更新多个数据表【英文标题】:ADO.NET - Updating Multiple DataTables 【发布时间】:2011-05-04 19:52:30 【问题描述】:

所以我有一些这样的代码:

        DataSet dataSet = new DataSet();            
        DataTable dataTable1 = new DataTable("Table1");
        DataTable dataTable2 = new DataTable("Table2");
        DataTable dataTable3 = new DataTable("Table3");
        DataTable dataTable4 = new DataTable("Table4");
        dataSet.Tables.Add(dataTable1);
        dataSet.Tables.Add(dataTable2);
        dataSet.Tables.Add(dataTable3);
        dataSet.Tables.Add(dataTable4);

        SqlDataAdapter dataAdapter1 = new SqlDataAdapter("SELECT * FROM Table1 WHERE ID = 1", sqlConnection);
        SqlDataAdapter dataAdapter2 = new SqlDataAdapter("SELECT Column1, Column2, Column3 FROM Table2", sqlConnection);
        SqlDataAdapter dataAdapter3 = new SqlDataAdapter("SELECT Column1, Column2, Column3 FROM Table3", sqlConnection);
        SqlDataAdapter dataAdapter4 = new SqlDataAdapter("SELECT Column1, Column2, Column3 FROM Table4", sqlConnection);

        SqlCommandBuilder commandBuilder1 = new SqlCommandBuilder(dataAdapter1);
        SqlCommandBuilder commandBuilder2 = new SqlCommandBuilder(dataAdapter2);
        SqlCommandBuilder commandBuilder3 = new SqlCommandBuilder(dataAdapter3);
        SqlCommandBuilder commandBuilder4 = new SqlCommandBuilder(dataAdapter4);            

        dataAdapter1.Fill(dataTable1);
        dataAdapter2.FillSchema(dataTable2, SchemaType.Source);
        dataAdapter3.FillSchema(dataTable3, SchemaType.Source);
        dataAdapter4.FillSchema(dataTable4, SchemaType.Source);

        //do a bunch of code that updates the one row from Table1
        //and adds lots of new rows to Table2, Table3, Table4

        dataAdapter1.Update(dataTable1);
        dataAdapter2.Update(dataTable2);
        dataAdapter3.Update(dataTable3);
        dataAdapter4.Update(dataTable4);
        dataSet.AcceptChanges();

有没有办法让这更简单?如果计算机在“dataAdapter2.Update(dataTable2);”之后在线崩溃会发生什么?我希望能够以某种方式仅使用一个更新调用来更新所有内容。这可能吗?

另外,这甚至是最好的方法吗? “this”是在多个表中创建一堆新行,具体取决于一个特定表中的一个特定行中的内容。

【问题讨论】:

【参考方案1】:

您可以将数据集传递到 DataAdapter 的更新语句中,这将更新数据集中的所有表。 更新:不,它不会。 DataAdapter 总是只更新一张表。从 MSDN documentation 到将 DataSet 作为其参数的 Update() 的重载,“从名为“Table “。”对困惑感到抱歉。不过,其余答案仍然有效。

如果您想确保所有更新作为一个原子单元成功或失败,请使用SqlTransaction 对象:

DataSet ds = new DataSet();
// do something with the dataset

SqlDataAdapter dataAdapter = new SqlDataAdapter();
SqlConnection cn = new SqlConnection(connString);
cn.Open();

SqlTransaction trans = cn.BeginTransaction();

SqlDataAdapter dataAdapter = new SqlDataAdapter();

// set the InsertCommand, UpdateCommand, and DeleteCommand for the data adapter

dataAdapter.InsertCommand.Transaction = trans;
dataAdapter.UpdateCommand.Transaction = trans;
dataAdapter.DeleteCommand.Transaction = trans;

try

    dataAdapter.Update( ds );
    trans.Commit();

catch

    trans.Rollback();


cn.Close();

【讨论】:

DataAdapter 如何知道如何更新存储在 DataSet 中的多个表?我使用了多个 DataAdapter,因为它们每个都从数据库中的不同表中选择,然后使用每个 DataAdapter 上的 CommandBuilder 自动构建更新/插入命令。 在回答您的问题时,我开始指出SqlDataAdapter.Update() 的MSDN documentation 具有接受DataSet 的重载。确实如此。但后来我看到了你的观点,并进一步挖掘。你是对的,DataAdapters 只更新一个表。采用 DataSet 的重载在 DataSet 中查找名为“Table”的表。我的错。我会相应地更新我的答案。 我也发现事情需要按这个顺序做:dA = new SqlDataAdapter("SELECT * FROM Table", cn); dA.SelectCommand.Transaction = tran; commandBuilder = new SqlCommandBuilder(dA); dA.InsertCommand = commandBuilder.GetInsertCommand(); dA.UpdateCommand = commandBuilder.GetUpdateCommand(); dA.DeleteCommand = commandBuilder.GetDeleteCommand(); dA.InsertCommand.Transaction = tran; dA.UpdateCommand.Transaction = tran; dA.DeleteCommand.Transaction = tran; 从测试中也可以看出,我不需要在事务中设置所有的插入、更新和删除命令,只需要设置选择命令来使用事务。 如果选择查询足够简单,SqlCommandBuilder 可以找出正确的插入和更新命令。但是,它并不总是有效,因此我建议将它们设置为小心。但如果它工作正常,那么一定要继续使用它。

以上是关于ADO.NET - 更新多个数据表的主要内容,如果未能解决你的问题,请参考以下文章

深入详解DataTable

Ado.net 断开更新整个表

ADO.NET 和数据集中的更新丢失

ADO.NET之使用DataSet类更新数据库

ADO .NET 中常用的对象有那些?分别描述下?

ado.net entity framework无法更新数据库