【问题标题】:Using an SQL Data Adapter to update and insert rows doesn't update (only inserts)使用 SQL 数据适配器更新和插入行不会更新(仅插入)
【发布时间】:2014-01-20 16:22:07
【问题描述】:

我现在只是在玩这个,最终我想将 CSV 文件读入内存,然后将记录插入 SQL 数据库。应更新现有记录,应添加缺失的记录。但是,不应删除新 CSV 中不存在的记录。

我一直在玩 MSDN 库中的示例。我知道 SqlDataAdapter 可以非常快速地执行批量更新。

我创建了一个小模拟应用程序,其中包含一个名为 TempTestTable 的表,其中包含 TempTestTableIdAgeName 列。我写了这个(基于MSDN Article):

using (SqlConnection connection =
   new SqlConnection("data source=localhost;initial catalog=fishsticks;integrated security=True;MultipleActiveResultSets=True;"))
{
    SqlDataAdapter dataAdpater = new SqlDataAdapter(
      "SELECT temptesttableid, Age, Name FROM TempTestTable",
      connection);

    dataAdpater.UpdateCommand = new SqlCommand(
       "UPDATE TempTestTable SET Age = @Age, Name = @Name " +
       "WHERE TempTestTableId = @TempTestTableId", connection);

    dataAdpater.InsertCommand = new SqlCommand(
       "INSERT INTO TempTestTable (Age, Name) " +
       "VALUES (@Age, @Name)", connection);

    SqlParameter parameter = dataAdpater.UpdateCommand.Parameters.Add(
       "@TempTestTableId", SqlDbType.Int);

    dataAdpater.InsertCommand.Parameters.Add(
      "@Age", SqlDbType.Int, 10, "Age");

    dataAdpater.InsertCommand.Parameters.Add(
      "@Name", SqlDbType.NVarChar, 50, "Name");

    dataAdpater.UpdateCommand.Parameters.Add(
      "@Age", SqlDbType.Int, 10, "Age");

    dataAdpater.UpdateCommand.Parameters.Add(
      "@Name", SqlDbType.NVarChar, 50, "Name");

    parameter.SourceColumn = "TempTestTableId";
    parameter.SourceVersion = DataRowVersion.Original;

    DataTable tempTestTable = new DataTable();

    tempTestTable.Columns.Add("Age");
    tempTestTable.Columns.Add("Name");
    tempTestTable.Columns.Add("TempTestTableId");

    var row1 = tempTestTable.NewRow();

    row1["Age"] = 10;
    row1["Name"] = "Smith";
    row1["TempTestTableId"] = 1;

    var row2 = tempTestTable.NewRow();

    row2["Age"] = 40;
    row2["Name"] = "Jones";
    row2["TempTestTableId"] = 2;

    tempTestTable.Rows.Add(row1);
    tempTestTable.Rows.Add(row2);

    dataAdpater.Update(tempTestTable);

数据库中已经有一条记录为TempTestTableId = 1,所以理论上它会更新该记录,并插入一条 ID 为 2 的新记录。但是,当我运行代码时,它会插入两个项目。

有什么想法吗?

【问题讨论】:

  • 不,DataAdapter 只会查看DataRowRowState property。如果是Added,则将执行InsertCommand,如果是Modified,则将执行UpdateCommand。您必须先将此行从数据库加载到表中。
  • 最初我从 MSDN 中提取的示例是这样做的,但我需要从 CSV 加载,所以我如何从数据库和 CSV 中读取?我是否必须将当前数据库表读入数据表,然后循环遍历它并根据我的 CSV 手动检查每一行,更改值或插入新行,并设置 RowState,然后提交?
  • 你可以用DataAdapter和你的SelectCommand填充一个空的DataTable,包括两个参数。如果表为空,您可以手动添加DataRow,否则您可以使用更新的值(如果有)修改行并调用dataAdpater.Update(tempTestTable)
  • 嗯,这听起来很混乱,你有例子吗?无论如何,我都会试一试
  • 想我已经明白了,我将我的数据库表加载到 DataTable 中,执行所有操作(添加、更新等)然后调用 .Update()。这似乎做到了,希望它会很快。

标签: c# sql sqldataadapter


【解决方案1】:

不,DataAdapter 只会查看 DataRow 的 RowState 属性。如果是Added,则将执行InsertCommand,如果是Modified,则将执行UpdateCommand。您必须先将此行从数据库中加载到表中。

您可以用DataAdapter 和您的SelectCommand 填充一个空的DataTable,包括两个参数。如果表为空,您可以手动添加DataRow,否则您可以使用更新的值(如果有)修改行并调用dataAdpater.Update(tempTestTable)

这是一个示例(未经测试):

SqlDataAdapter dataAdpater = new SqlDataAdapter(
  "SELECT temptesttableid, Age, Name FROM TempTestTable WHERE Name = @Name",
  connection);

DataTable testTable = new DataTable();
// note that you should use an available csv-parser instead
foreach (string line in File.ReadAllLines(path))
{ 
    string[] columns = line.Split(new char[]{'\t'}, StringSplitOptions.None);
    if(columns.Length >= 2)
    {
        string name = columns[0].Trim();
        string ageStr = columns[1].Trim();
        int age;
        if (int.TryParse(ageStr, out age))
        {
            dataAdpater.SelectCommand.Parameters.AddWithValue("@Name", name);
            int rowsAdded = dataAdpater.Fill(testTable);
            if (rowsAdded == 0)
            {
                testTable.Rows.Add(name, age);
            }
            else
            {
                // update values?
            }
        }
    }
}
dataAdpater.Update(testTable);

【讨论】:

  • 谢谢,将着手实施。我想在更新值部分我必须定义一个 UpdateCommand 并以某种方式执行它。实际上,如果没有定义 AddCommand,我不确定 AddWithValue 将如何工作......
猜你喜欢
  • 2017-06-25
  • 2018-07-13
  • 2015-05-24
  • 2021-11-07
  • 2014-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多