【问题标题】:using DataAdapter to populate table使用 DataAdapter 填充表
【发布时间】:2011-08-13 08:00:32
【问题描述】:

我有一个断开连接的dataTable,其中包含一些记录。

我正在使用以下函数来获取dataTable

static System.Data.DataTable ReadSetUpTable(string queryStr,SqlConnection sc)
{
    try
    {
        var command = new SqlCommand()
                          {Connection = sc, CommandText = queryStr};
        var dataAdapter = new SqlDataAdapter() {SelectCommand = command};
        var dataTable = new System.Data.DataTable();
        dataAdapter.Fill(dataTable);
        return dataTable;
    }
    catch (Exception)
    {
        throw;
    }
} 

目前没有问题。

我想知道是否可以使用不同的连接字符串轻松将此dataTable 填充到另一个架构中。

为了这篇文章,假设有一个包含两列的表

Create Table Student(StudentId NUMBER(6), StudentName varchar2(50));

我希望用上面代码中的dataTable 填充此表。

我可以使用命令对象和插入语句来做到这一点。例如这段代码:

static int LoadDataTable(OracleConnection oc, System.Data.DataTable dataTable)
{
    try
    {
        var command = 
            new OracleCommand
            {
                CommandText = "INSERT INTO STUDENT (STUDENTID, STUDENTNAME) VALUES(:studentid, :studentname)",
                CommandType = CommandType.TableDirect,
                Connection = oc
            };
        var op1 = 
            new OracleParameter
            {
                ParameterName = "StudentId",
                Size = 6,
                OracleDbType = OracleDbType.Int32,
            Direction = System.Data.ParameterDirection.Input
            };
        command.Parameters.Add(op1);
        var op2 = 
        new OracleParameter
            {
                ParameterName = "studentName",
                OracleDbType = OracleDbType.Varchar2,
                Size = 50,
                Direction = System.Data.ParameterDirection.Input
            };
        command.Parameters.Add(op2);                                   
       /*
        foreach (var row in dataTable.Rows)
        {
            op1.Value = int.Parse(row[0].ToString());
            op2.Value = row[1].ToString();
            command.ExecuteNonQuery();
        }*/
            foreach (System.Data.DataRow row in dataTable.Rows)
            {
                row.SetAdded();
            }    

            var dataAdapter = new OracleDataAdapter() {InsertCommand = command};
            dataAdapter.Update(dataTable); //This updates the table, but all column values are NULL.

    }
    catch(Exception)
    {
        throw;
    }
} 

有没有一种更快、更简单的方法让我不必遍历记录?

【问题讨论】:

    标签: c# .net datatable dataadapter


    【解决方案1】:

    在您的第一个代码块中,您设置了SelectCommand。还有一个InsertCommandUpdateCommandDeleteCommand

    这些命令也存在于OracleDataAdapter 对象上...由于DataTable 是端点中立的,您需要做的就是创建一个OracleCommand 来进行插入,将其设置为OracleDataAdapter's @ 987654330@,并拨打oracleDataAdapter.Update(dataTable)

    在我检查它们时会用更多细节来修改它。


    设置InsertCommand 的一个很好的例子是here。请注意,当您向命令添加参数时,您传递给.Add( ... ) 的最后一个值是您要映射到的列的名称。

    因为您正在将数据检索到 DataTable 中,但没有对其进行更改,因此您需要在调用 oracleDataAdapter.Update() 之前将每行的 RowState 更改为“已添加”。您需要执行以下操作:

    foreach (DataRow row in dataTable.Rows) {
        row.SetAdded();
    }
    

    如果您需要更多代码示例,请告诉我...从您发布的代码中,我想您已经大致了解了我要去的地方。


    编辑

    创建OracleParameters时,需要将源列设置为DataTable中的列名。默认情况下,这是 select 语句返回的名称,所以:

    var op1 = new OracleParameter {
                                    ParameterName = "StudentId",
                                    Size = 6,
                                    OracleDbType = OracleDbType.Int32,
                                    Direction = System.Data.ParameterDirection.Input
                                    SourceColumn = "StudentId" // If that's what it's called in the DataTable
                                  };
    command.Parameters.Add(op1);
    

    AcceptChanges() 方法位于 DataTable 上,HasErrors 属性也是如此(它也存在于 DataRowsDataSets 上)。

    AcceptChanges() 仅告诉 DataTable 您已经处理了对数据库的更新...当您调用 oracleDataAdapter.Update() 时,更改将提交给数据库。您调用 AcceptChanges() 的原因是重置行状态...否则下次更新 DataTable 时,您将尝试添加已添加的行。

    OracleDataAdapter 上的属性 AcceptChangesDuringUpdate 将自动调用 AcceptChanges() 作为数据库更新的一部分...我通常不这样做,因为我习惯于测试 HasErrors 属性并在调用AcceptChanges() 之前处理这些问题...但是我读到AcceptChanges() 现在在更新时默认调用。我不熟悉如何处理错误行的详细信息,是否接受更改。

    【讨论】:

    • @James B - 你在哪里将dataAdapter的数据源设置为dataTable?
    • @James:dataTable.AcceptChanges() 会有效地将所有rows 设置为已添加吗?
    • 你不...就像你调用 dataAdapter.Fill(dataTable),你调用 oracleDataAdapter.Update(dataTable)。
    • 不,这会适得其反……AcceptChanges() 会将标记为“已添加”、“已修改”等的所有内容设置为“未更改”。在调用 oracleDataAdapter.Update(dataTable) 并且所有行都已成功更新(使用 DataTable 的 HasErrors 属性确定是否有任何行失败)之后,您调用 AcceptChanges()
    • @JamesB 我已经修改了我的代码。请看一下。我已经能够在 Student 表中插入行,但所有列都是空的。 OracleDataAdapter 上没有AcceptChanges() 方法。AcceptChangesDuringFill 和AcceptChangesDuringUpdate 有两个属性。 AcceptChanges 位于 dataRow 上。
    猜你喜欢
    • 2011-06-22
    • 2013-04-11
    • 2017-07-26
    • 1970-01-01
    • 2014-10-29
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    相关资源
    最近更新 更多