SqlDataAdapter.Update молча завершается ошибкой - PullRequest
1 голос
/ 11 августа 2011

В моем приложении у меня есть элемент управления, который отображает содержимое таблицы базы данных пользователю. Этот элемент управления содержит данные для отображения в System.Data.DataSet объекте. Пользователь может изменять данные, отображаемые в элементе управления, и эти данные затем возвращаются в базу данных, когда пользователь завершает работу.

Проблемы возникают, когда данные в таблице базы данных изменяются каким-либо внешним процессом (например, некоторые строки были обновлены), когда пользователь вносит изменения в элемент управления. Игнорируя вопрос о правильности данных на данный момент, я хотел бы зафиксировать изменения, внесенные пользователем в элемент управления, и перезаписать изменения, сделанные этим внешним процессом.

Я использую SqlDataAdapter для обновления базы данных. В описанных случаях использования, когда базовая таблица базы данных не была изменена внешним процессом, SqlDataAdapter.Update работает как ожидалось. Однако в сценарии, когда какой-то внешний процесс поиграл с таблицей, когда пользователь ее редактировал, SqlDataAdapter.Update не выдает исключение, а возвращает 0, указывая, что строки не были обновлены. Я проверил, что строки в моем наборе данных имеют правильные данные и RowState (т.е. DataRowState.Modified), поэтому я знаю, что данные, которые я передаю в метод SqlDataAdapter.Update, верны.

Полагаю, в моем вопросе есть две части.

  1. Почему SqlDataAdapter.Update не обновляет базу данных указанным набором данных?
  2. Почему он молча терпит неудачу?

Я прочитал эту запись в блоге , и мой код нигде не вызывает AcceptChanges, и, как я уже говорил выше, я проверил DataSet RowState, поэтому я знаю, что строки правильно помечены как имеющие измененные данные.

1 Ответ

1 голос
/ 11 августа 2011

Какова структура вашей таблицы и какой механизм контроля версий (отметка времени, дата и т. Д.) Вы используете? Существует ряд факторов, которые могут повлиять на то, как SqlDataAdapter в конечном итоге будет обрабатывать версии, но я предполагаю, что у вас либо есть временная метка в таблице, либо SqlCommandBuilder который генерирует SqlCommand (с помощью метода GetUpdateCommand), который в конечном итоге проверяет все значения в строке в базе данных на соответствие предыдущим значениям в строке, которую вы обновили (DataRow хранит предыдущую версию строки для сравнения).

Все это играет роль, потому что ADO.NET будет пытаться поддерживать оптимистичный параллелизм для вас; если кто-то еще изменил запись с момента последней загрузки, обновление не произойдет.

Это явно не то поведение, которое вам нужно; вам нужен подход «последний в выигрыше».

Для этого на SqlDataAdapter задайте для свойства UpdateCommand явное значение SqlCommand, которое будет выполнять обновление, а не проверять отметку времени, оно только обновляет запись, в которой первичный ключ равно указанному вами значению в DataRow (или значению в столбце, для которого установлено уникальное ограничение).

...