SqlDataAdapter 不更新数据库中的行

本文关键字:数据库 更新 SqlDataAdapter | 更新日期: 2023-09-27 18:36:26

我正在使用SqlDataAdapter来更新我的dataTable,我在另一种方法中从数据库中查询了该表,并且在该方法中更新了列,状态和Is_processed。
现在,我希望这些更改在数据库中持久保存(更新)。以下是为实现目标所做的工作:

法典

 batchSize = 10;
string cmd;
    int updatedRows;
    try
    {
        string connString = db.ConnectionString;
        using (SqlConnection conn = new SqlConnection(connString))
        using (SqlDataAdapter adapter = new SqlDataAdapter())
        {
            cmd = "UPDATE IMPORTED_ACCOUNTS SET STATUS = @Status , IS_PROCESSED = @IsProcessed " +
                   ", CREATED_ON = @CreatedOn , CREATED_BY = @CreatedBy , UPDATED_ON = @UpdatedOn , UPDATED_BY = @UpdatedBy " +

 "WHERE CONVENTIONAL_ACCOUNT = @ConAcct";
        adapter.UpdateCommand = new SqlCommand(cmd, conn);
        adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
        adapter.UpdateCommand.Parameters.AddWithValue("@Status", "Status");
        adapter.UpdateCommand.Parameters.Add("@IsProcessed", SqlDbType.Bit, 1, dTable.Columns["IsProcessed"].ColumnName);
        adapter.UpdateCommand.Parameters.Add("@CreatedOn",SqlDbType.DateTime,30, dTable.Columns["CreatedOn"].ColumnName);
        adapter.UpdateCommand.Parameters.AddWithValue("@CreatedBy", dTable.Columns["CreatedBy"].ColumnName);
        adapter.UpdateCommand.Parameters.Add("@UpdatedOn",SqlDbType.DateTime,30, dTable.Columns["UpdatedOn"].ColumnName);
        adapter.UpdateCommand.Parameters.AddWithValue("@UpdatedBy", dTable.Columns["UpdatedBy"].ColumnName);
        adapter.UpdateCommand.Parameters.AddWithValue("@ConAcct", dTable.Columns["ConventionalAccount"].ColumnName);
        cmd = "INSERT INTO IMPORTED_ACCOUNTS ([STATUS],[IS_PROCESSED],[CREATED_ON],[CREATED_BY],[UPDATED_ON],[UPDATED_BY], CONVENTIONAL_ACCOUNT) " +
              "VALUES (@Status , @IsProcessed, @CreatedOn, @CreatedBy, @UpdatedOn, @UpdatedBy, @ConAcct) ";
        adapter.InsertCommand = new SqlCommand(cmd, conn);
        adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
        adapter.InsertCommand.Parameters.AddWithValue("@Status", dTable.Columns["Status"].ColumnName);
        adapter.InsertCommand.Parameters.Add("@IsProcessed", SqlDbType.Bit, 1, dTable.Columns["IsProcessed"].ColumnName);
        adapter.InsertCommand.Parameters.Add("@CreatedOn", SqlDbType.DateTime, 30, dTable.Columns["CreatedOn"].ColumnName);
        adapter.InsertCommand.Parameters.AddWithValue("@CreatedBy", dTable.Columns["CreatedBy"].ColumnName);
        adapter.InsertCommand.Parameters.Add("@UpdatedOn", SqlDbType.DateTime, 30, dTable.Columns["UpdatedOn"].ColumnName);
        adapter.InsertCommand.Parameters.AddWithValue("@UpdatedBy", dTable.Columns["UpdatedBy"].ColumnName);
        adapter.InsertCommand.Parameters.Add("@ConAcct", SqlDbType.VarChar, 100, dTable.Columns["ConventionalAccount"].ColumnName);
        cmd = "DELETE FROM IMPORTED_ACCOUNTS WHERE CONVENTIONAL_ACCOUNT = @ConAcct";
        adapter.DeleteCommand = new SqlCommand(cmd, conn);
        adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
        adapter.DeleteCommand.Parameters.AddWithValue("@ConAcct", dTable.Columns["ConventionalAccount"].ColumnName);
        adapter.UpdateBatchSize = batchSize;
        updatedRows = adapter.Update(dTable);  // point where code breaks
    }
    return updatedRows;
}
catch (Exception ex)
{
    return 0;
}

错误

它最终在 catch 块中出现以下错误:

违反主键约束"PK_ACCTS"。无法插入 对象'dbo'中的重复键。IMPORTED_ACCOUNTS'。

评论为什么它试图在数据库中插入应该更新的行,因为它们已经存在于数据库中?适配器的条件是什么。更新(dTable)方法,当它触发更新而不是插入时?

想不通...确实非常感谢帮助!

SqlDataAdapter 不更新数据库中的行

在 .NET 中,DataAdapter根据DataRow.RowState属性进行数据库更改。

在具有Added值的情况下 - 数据适配器将尝试插入记录。如果需要更新记录 - 则此属性应具有Modified值。

您不能直接设置 od RowState 的值。例如,它已设置为在向数据表添加行时自动Added

Hovewer,您仍然可以间接修改此值。为此,您应该调用 DataRow.AcceptChanges 以获取需要更新的 thouse 数据行,这会将RowState设置为 Unchanged 。然后,您应该修改这些数据行中的任何内容,在这种情况下,它们将具有 RowState = Modified .

适配器将根据表中每一行的DataRow.RowState来决定何时插入、更新或删除。有关可能的状态,请参阅 https://msdn.microsoft.com/es-es/library/system.data.datarowstate(v=vs.110).aspx。

填写数据表后,可以调用 DataTable.AcceptChanges 方法将所有行标记为未更改。

此外,如果您有自动数字 PK,则最佳做法是使用以下属性在 DataTable 中设置该字段:

  • 自动增量:真
  • 自动增量种子: -1

最后一个确保如果在数据表中插入新值,则新 ID 值不会与现有 ID 值冲突