|
Добавление записей в Master-Details DataSet
|
|||
---|---|---|---|
#18+
Столкнулся со следующей проблемой. У меня есть DataSet, содержащий 2 таблицы, одна из которых ссылается на другую. Обычный Master-Details. Задача состоит в том, чтобы добавить в таблицу details новые записи, которые могут ссылаться на новые записи в таблице master. При этом имеется осложняющее обстоятельство. Identity в master-таблице будет известно только после реального добавления записей в базу данных (backend - MS SQL 2K). При добавлении на клиенте просто используются временные ключи, чтобы обеспечить соблюдение ограничений. Казалось бы все просто - получаем новые строки из master-таблицы, делаем Update на DataAdapter'e. Команда у нас - хранимая процедура, ключ в выходных параметрах, отображенных на нужные поля в таблице DataSet'a, значения в полях вторичного ключа во 2-й таблице обновляются каскадно, так что сгенерированное на сервере значение ключа оказывается во всех нужных полях... Вроде бы осталось только получить новые строки из подчиненной таблицы и натравить Update соответствующего адаптера на них... А фигушки - строки в таблице details после каскадного обновления находятся в состоянии Unchanged, естественно Update их игнорирует. Пока нашел такое решение. Получаю набор новых строк из подчиненной таблицы до проведения обновления master-таблицы. Затем обновляю master-таблицу. После этого пробегаю по набору новых строк подчиненной таблицы и те из них, что имеют состояние Unchanged пихаю в клон этой подчиненной таблицы. Далее клон отправляется в Update, исходный набор новых строк также отправляется в Update, там могли остаться новые записи, ссылающиеся на уже существующие в master-таблице строки. Это работает, но возможно существует более красивое и правильное решение. Поделитесь опытом, пожалуйста. ===== Не дождетесь! ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2004, 08:06 |
|
Добавление записей в Master-Details DataSet
|
|||
---|---|---|---|
#18+
Тут можно обойтись без клона. Но проблема очевидно раньше привидите свой код. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2004, 11:14 |
|
Добавление записей в Master-Details DataSet
|
|||
---|---|---|---|
#18+
Код обновления такой: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26.
Больше ничего особенного там нету, DataSet, таблицы, 2 адаптера сделаны в дизайнере. Редактирование через грид. Отклонения от умолчаний - В схеме данных набора данных явно указаны UpdateRule и DeleteRule, выставлено значение Cascade - Текст для команд в адаптере я сам написал Собственно все. Я просто воспроизводил на своем примере содержание материала: Walkthrough: Creating a Master-Detail Windows Form ===== Не дождетесь! ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2004, 13:04 |
|
Добавление записей в Master-Details DataSet
|
|||
---|---|---|---|
#18+
Было бы хорошо если бы вы немножко комментировали код, а код constraintа привести можете? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2004, 14:23 |
|
Добавление записей в Master-Details DataSet
|
|||
---|---|---|---|
#18+
Код констрайнта я сам не писал, так что комментарий будет перед кодом 1. Таблица cls_user, ключ user_id типа int. В схеме сделан автоинкремент, в реальной таблице на сервере его нет. 2. Таблица ip_user, ключ ip_ip varchar(255), поле ip_uid ссылается на ключ в таблице cls_user Что касается, предыдущего фрагмента кода, то он (могу ошибаться) слишком прост для комментирования. Там всего лишь производится упорядочение внесения изменений с учетом связи между таблицами. 1. При добавлении записей строки в родительскую таблицу должны быть добавлены раньше, чем в подчиненную для поддержания ссылочной целостности. При удалении - наоборот, из дочерней таблицы строки надо удалить раньше. Изменение существующих записей - все равно когда проводить, у меня после вставки и перед удалением. 2. При добавлении записей в родительскую таблицу, строки получаются вызовом Код: plaintext
потому что мне нужно вставить значения реального (а не клиентско-автоинкрементного ключа) обратно в таблицу набора данных. Select в отличие от GetChanges возвращает ссылки на оригинальные строки, а не клон таблицы. Очевидно, что если не заменить значения на реальные, после первого же вызова <имя адаптера>.Fill(setMain.cls_user) пользователь получит несуществующие дубли строк. Собственно Constraint: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
Собственно, вот схема данных в DataSet: 1. Таблица cls_user, ключ user_id типа int. В схеме сделан автоинкремент, в реальной таблице на сервере его нет. 2. Таблица ip_user, ключ ip_ip varchar(255), поле ip_uid ссылается на ключ в таблице cls_user Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43.
===== Не дождетесь! ... |
|||
:
Нравится:
Не нравится:
|
|||
24.03.2004, 15:43 |
|
Добавление записей в Master-Details DataSet
|
|||
---|---|---|---|
#18+
Ну то что я хотел увидеть к сожалению не увидел :-( DataAdapter при Update меняет state Modified, Added, Deleted в Unchanged у Detail только в том случае когда у constraint стоит AcceptRejectRule = AcceptRejectRule.Cascade. По умолчанию должно быть None у вас же явно он не выставлен то есть по идее update не должен был коммитить записи Detail. Одно из возможных решений: Добавить следующую строчку, или сделать это через схему: Код: plaintext 1. 2. 3. 4.
Теперь после update Masterа ничего не должно коммититься, поставьте для проверки выдачу количество записей Modified, Deleted, Added до DataAdapter.Update , и после например так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.
setMain.AcceptChanges() // можно убрать пока (но не навсегда :-) ) Тогда станет понятно что же происходит после очередного update, когда я говорил про комментарии к вашему коду как раз это и имел ввиду. Например вы могли его прокоменнтировать так: M - master table, D - detail table, " До первого update - M ( 1 удал, 2 добавл, 0 модифи), D (2 удал, 4 добавл, 0 модифици) После первого update - M (0, 0, 0 ), D(0, 0, 0 ) После второго update ...... или подобным образом. " Хотя приведенные в другом вашем посте комментарии тоже не лишние. > Текст для команд в адаптере я сам написал Можете для InsertCommand привести код? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.03.2004, 08:01 |
|
|
start [/forum/topic.php?fid=17&tid=1354181]: |
0ms |
get settings: |
11ms |
get forum list: |
13ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
30ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
52ms |
get tp. blocked users: |
2ms |
others: | 12ms |
total: | 147ms |
0 / 0 |