2016-02-26 4 views
0

Я использую SqlDataAdapter для обновления моей таблицы данных, которую я запросил из базы данных в другом методе, и в этом методе были обновлены столбцы, Status и Is_processed.
Теперь я хочу, чтобы эти изменения сохранялись (обновлялись) в базе данных. Вот, что было сделано для достижения:SqlDataAdapter не обновляет строки в базе данных

Кода

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; 
} 

Ошибка

Он заканчивается со следующей ошибкой в ​​уловах блоке:

нарушения PRIMARY KEY ограничение «PK_ACCTS». Невозможно вставить дубликат ключа в объекте 'dbo.IMPORTED_ACCOUNTS'.

Комментарий Почему она пытается вставить строки в базе данных, когда они должны быть обновлены, поскольку они уже существуют в базе данных? Каковы условия для метода adapter.Update (dTable), когда он запускает Update скорее Insert?

Не могу понять ... Помощь действительно ценится!

+0

Проверьте 'RowState'' DataRows', который вы пытаетесь обновить. Если у них есть 'Добавлено 'rowstate - тогда dataadapter попытается вставить соответствующие записи. –

+0

Я только что проверил свойство RowState и да, это имеет значение «Добавлено». Что мне теперь делать? Сделать его нулевым? – Sadiq

+0

Вы проверили здесь: https: //msdn.microsoft.com/en-in/library/z1z2bkx2 (v = vs.110) .aspx – TheGameiswar

ответ

2

В .NET DataAdapter делает da tabase изменяется в соответствии с DataRow.RowState.

В случае, когда оно имеет значение Added - dataadapter попытается вставить записи. Если вам нужно обновить записи - тогда это свойство должно иметь значение Modified.

Вы не можете прямо установить значения RowState. Например, он был установлен на Added автоматически, когда вы добавляете строки в свою таблицу данных.

Hovewer, вы по-прежнему можете косвенно изменить это значение. Чтобы сделать это, вам нужно позвонить DataRow.AcceptChanges для этих данных, которые вам нужно обновить, это установит RowState в Unchanged. Затем вы должны изменить что-либо в этих datarows, и в этом случае они будут иметь RowState = Modified.

1

Адаптер будет решать, когда вставлять, обновлять или удалять на основе DataRow.RowState каждой строки в таблице. См. https://msdn.microsoft.com/es-es/library/system.data.datarowstate(v=vs.110).aspx для возможных состояний.

После заполнения DataTable вы можете вызвать метод DataTable.AcceptChanges, чтобы пометить все строки как неизменные.

Кроме того, если у вас есть autonumeric PK, является лучшим, что установка поля в DataTable с этими свойствами практика:

  • Autoincrement: истинный
  • AutoIncrementSeed: -1

Последняя убедитесь, что если вы вставляете новые значения в свой datatable, новые значения ID не будут конфликтовать с существующими

Смежные вопросы