sqldataadapter多个表和事务

时间:2011-11-09 22:32:34

标签: c# ado.net rollback dataadapter sqldataadapter

ADO.NET - Updating Multiple DataTables

我发现上面的问题正是我正在寻找并尝试实施解决方案......

我正在尝试查看将多个表更新到sqlserver 2008并确保多个表上的事务的最佳解决方案。如果插入一个表失败,则回滚其他表上的先前更新。

  1. sqldataadapter一次仅更新一个表
  2. 我知道我们可以一次在一个dataadapter上执行事务,但需要更新多个表
  3. 以下是根据上面提供的答案修改的代码,但是数据适配器出错了。我想我需要设置插入,更新和删除命令,但不知道如果有多个表,它是如何工作的???有人可以填写缺失的链接吗?

            using (SqlConnection con = new SqlConnection(SqlServerConnectionString))
            {
                con.Open();
                //table is an array of datatable and contains data to be inserted
                for (int i = 0; i < table.Length; i++)
                {
                    ds.Tables.Add(table[i]);
                }
    
                SqlTransaction trans = con.BeginTransaction();
    
                SqlDataAdapter dataAdapter = new SqlDataAdapter();
                //Need to set insert,select, update, delete???? on multiple tables?
    
                //dataAdapter.Fill(ds);
                dataAdapter.InsertCommand.Transaction = trans; //null object error here
                dataAdapter.UpdateCommand.Transaction = trans;
                dataAdapter.DeleteCommand.Transaction = trans;
    
                try
                {
    
                    dataAdapter.Update(ds);
                    trans.Commit();
                }
                catch(Exception ex)
                {
                    trans.Rollback();
    
                }
    

2 个答案:

答案 0 :(得分:1)

感谢大家的投入。我想之前@Charlie用这个q / a回答了我:ADO.NET - Updating Multiple DataTables

我想也许您可以使用数据集进行更新,但我想您仍然需要创建其他数据适配器,然后调用update。因此,前一个问题的答案是唯一的另一种简化方法,即@ gamzu07想要做的是使用数组而不是每次都声明它。下面的代码有效,但似乎对我迟钝,除了可能构建插入命令并执行它之外,是否有任何人有更好的想法....?

            SqlDataAdapter[] dataAdapter = new SqlDataAdapter[table.Length];

            for (int i = 0; i < table.Length; i++)
            {

                dataAdapter[i] = new SqlDataAdapter("select * from " + table[i].TableName, con);
                SqlCommandBuilder cb = new SqlCommandBuilder(dataAdapter[i]);
                dataAdapter[i].InsertCommand = cb.GetInsertCommand();
                dataAdapter[i].Fill(table[i]);

            }

            SqlTransaction trans = con.BeginTransaction();

            try
            {
                for(int i=0;i < table.Length;i++){
                    dataAdapter[i].InsertCommand.Transaction = trans;
                    dataAdapter[i].Update(table[i]);
                }
                trans.Commit();
            }
            catch(Exception ex)
            {
                trans.Rollback();
            }

答案 1 :(得分:0)

你需要为每个命令定义命令 - 我建议使用SqlCommandBuilder来完成这项工作。

但请注意,SqlDataAdapter仅适用于一个 DataTable。如果这是第一个表格,则不清楚文档:

  

Update方法在执行更新之前从第一个映射中列出的表中检索行。

http://msdn.microsoft.com/en-us/library/system.data.common.dataadapter.update.aspx

...或者也许只是DataSet中唯一一个名为Table的表:

  

更新|从名为“Table”的DataTable中为指定DataSet中的每个插入,更新或删除的行调用相应的INSERT,UPDATE或DELETE语句。

http://msdn.microsoft.com/en-us/library/system.data.common.dataadapter.update.aspx

在任何情况下,如果您使用的是SqlDataAdapter,那么您对表的循环将需要调用Update。

修改

在任何情况下,据我所知,SqlDataAdapter在这里不是一个好选择。如果您要做的只是在DataTables之间共享一个事务,那么只需使用一系列共享SqlTransaction的SqlCommands。

(如果这还不够清楚,我将在上班时添加代码示例)