| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Базы данных под .NET > Удаление вновь созданный записи |
| Автор: albert21 8.3.2006, 17:06 | ||||
Проблема: В одной из таблиц базы данных создаётся новая запись
Сразу после появления этой записи в гриде, выделяем её и нажимаем кнопку "Удалить":
И вот тут может появиться ошибка! Подчёркиваю МОЖЕТ. Ошибка появляется на последней строке приведённого кода: AdapterDisk.Update(dts, "Disk"); Ругается следующими словами: Concurrency violation: the DeleteCommand affected 0 of the expected 1 records. Подскажите пожалуйста как решить |
| Автор: mr.DUDA 8.3.2006, 17:56 |
| Видимо, адаптер толком не понимает что ему делать с записью, которую добавили а потом удалили - добавлять и удалять из БД ? |
| Автор: albert21 8.3.2006, 19:58 |
| В пошаговом режиме после нажатия кнопки "ДОБАВИТЬ" в базе данных действительно появляется запись. Возможно запись в ДатаСет имеет некое специальное состоянние, когда факт обновления не подтверждён! Но это только мои догадки! Есть метод который бы железно подтвердил ранее внесённые изменения в набор данных? |
| Автор: -ser- 9.3.2006, 05:54 | ||||||||
| стоп, стоп, стоп. все не совсем так. не четко описаны намерения, в каком состоянии наши записи, когда мы что-то дальше пытаемся с ними делать.
здесь очень важно на каком этапе мы хотим удалить запись?
именно так! существует несколько промежуточных версий и состояний записи, а именно аж 4 разных версии : current, original, default, proposed. и 5 разный состояний: added, deleted, detached, modified, unchanged. и механизм ее удаления зависит от того, в какой версии и в каком состоянии она находится в данный момент. и если мы ее видим в БД или в гриде, после того же добавления, это еще совсем ни о чем не говорит. существует как минимум 3 основных табличных метода:
и 8 основных методов манипуляций с записью:
использование которых влияет как на версию, так и на состояние записи(сей). не буду приводить сюда подробный механизм работы всего вышеописанного. это заслуживает отдельной темы. да дело даже и не в этом. в мире много всего более интересного, если конечно у нас не банковское приложение, с четким механизом отката транзакций в зависимости от ситуаций. вернемся к нашей задаче. для упрощения, отложим в сторону все, о чем я писал выше. договоримся, что любые изменения мы сразу же записываем в базу. неэффективно, но ошибки исключены. 1. правильнее Adapter.Update делать не на весь ДатаСет, а только на измененные записи. http://forum.vingrad.ru/index.php?showtopic=76977 2. после этого, либо делаем dataSet.AcceptChanges(), либо, для чистоты эксперимента, возьмем и перезальем наш ДатаСет, предварительно его очистив dataSet.Clear(); тоже самое с удалением. проще некуда. З.Ы. все это относится к ADO.NET, в ADO.NET 2.0 кое-что изменилось, но концепция та же. Что появилось нового, например, можно обойтись вообще без ДатаСета. ДатаТейбл уже стала независимой от ДатаСета и имеет колоссальную функциональность. |
| Автор: albert21 9.3.2006, 12:05 | ||
Написал так:
1) В таком варианте удаления не происходит вообще! Нет из ДАТАГРИД всё удаляется, а из базы НЕТ! Виноват в этом sRow.AcceptChanges(); Этот метод даже по названию должен потверждать удаление, он же по факту его отменяет. Чего-то я не пойму!!! 2) Без sRow.AcceptChanges(); Изменений никаких, та жа ошибка. Ставил dts.AcceptChanges();, xDataSet.AcceptChanges(); до обновления adapter.Update(xDataSet, "Disk");, результат: из ДАТАГРИД всё удаляется, а из базы НЕТ! Может я чего-то не догоняю, объясните плиз!!! |
| Автор: -ser- 10.3.2006, 07:49 | ||
| все правильно, смотри что происходит, xхх.AcceptChanges() у тебя сбрасывает все флаги изменений, и, соответственно, dts.GetChanges(...) не зафиксирует никаких изменений. пока не разберешься с версиями и состояниями, просто не используй Accept/RejectChanges. adaptor.Update() cам вызовет AcceptChanges().
|
| Автор: albert21 10.3.2006, 15:51 |
| Всё равно та жа ошибка на Update(). И потом перезалить датасет на мой взгляд не самое лучшая идея с точки зрения производительности. Может хорошая книжка (на русском) электронная по C# + ADO.NET у кого нибудь есть? |
| Автор: -ser- 12.3.2006, 08:51 |
| на этом форуме специальный раздел посвящен этому, где тонны литературы на любой вкус, уж не ленитесь посмотреть. можешь посмотреть вот это http://www.zipsites.ru/books/almanakh_programmista_tom1/ если честно, сам так и не читал, почти всегда хватает MSDN. по твоему примеру, попробуй адаптер и основной датасет сделать глобальными. |
| Автор: albert21 12.3.2006, 11:14 |
| Раздел есть конечно, но там не указано на каком языке книга! |
| Автор: albert21 12.3.2006, 13:56 | ||||
| Проблема заключается в том, что при добавлении новой записи в DataSet эта запись получает значение автоинкремента от DataSet, которое формируется из значения последней записи прочитанной из базы данных увеличенного на единицу. В самой же базе данных значение автоинкремента может быть совершенно другим!!!. Для того чтобы избавиться от ошибки необходимо повесить обработчик на Adapter:
Теперь вопрос: Как получить значение автоинкремента из БД MS Access????? ДЛя MS SQL прокатит так вроде:
Добавлено @ 13:59 Чуть не забыл!!! Добрый совет: все украшения, типа "НАДО СКРЫТЬ НЕ НУЖНЫЕ ДЛЯ ПОЛЬЗОВАТЕЛЯ ПОЛЯ" делайте в самую последнюю очередь |
| Автор: arilou 14.3.2006, 01:06 |
| SELECT @@IDENTITY для Аксеса не прокатывает, поэтому надо делать (другого способа не знаю) SELECT MAX(FieldID) FROM Table. |
| Автор: albert21 14.3.2006, 19:24 | ||||
Это тоже не пойдёт, так как записи в БД могут удаляться, а счётчик БД при этом не уменьшается. Я решил проблему так: убираем счётчик вообще, делаем поле ID просто целочисленным, а при запуске приложения пишем
Если кто более удачное решение нароет, скиньте плиз! |