Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/56: Рейтинг темы: голосов - 56, средняя оценка - 5.00
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
1

Как вы делаете Update данных в БД (при использовании DataGridView, DataSet, DataAdapter)

22.02.2012, 12:04. Просмотров 10561. Ответов 31
Метки нет (Все метки)

Доброго дня, форумчане.
Отдельный привет знакомым форумчанам.

Решил поднять я старую наболевшую тему про DGV и DS. Тыщу лет назад я уже об этом спрашивал, более того подискутировал на эту тему (здесь). В прошлый раз я вывернулся и избежал спорных моментов в этом вопросе. Но вот опять прихожу к тому же.

Итак суть:
Преамбула: Создаю подключение к БД руками в коде, использую DataAdapter, DataSet. К DataGridView цепляется таблица DataSeta (все как "по учебнику")

Хочу при нажатии на строки грида вызывать форму (т.н. карточку-документа) из которой добавлять или изменять строки в гриде.

С добавлением строк в грид (в ДатаСет и потом в БД) никаких проблем нет - создаю объекты DataRow, добавляю их в DataTable и.т.д.

А вот с банальным обновлением (читай изменением\Update'ом) - всё крайне сложно.

Известно, что если изменить строку в гриде и проапдейтить ДатаСет, данные обновятся и в БД (то есть нет надобности лезть в ДатаСет, ворочать его объекты DataRow)

Интересно то, что если в одну процедуру (например нажатия на кнопку) толкать изменение строк грида и обновление ДатаСета, то данные не попадают в БД. Если эти функции разбить (например по разным кнопкам) - все замечательно работает.

Чтобы не быть голословным...

Вот код который работает (два действия на разных кнопках):
vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 
        dgv1.BeginEdit(True)
        dgv1.CurrentRow.Cells("Заказ").Value = TextBox1.Text
        dgv1.CurrentRow.Cells("Наименование").Value = TextBox2.Text
        dgv1.EndEdit()
End Sub
 
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
 da.UpdateCommand = cmdBuilder.GetUpdateCommand
 da.Update(ds, ds.Tables(0).TableName)
 ds.AcceptChanges()
End Sub
а вот код который НЕ работает:

vb.net
1
2
3
4
5
6
7
8
9
10
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        dgv1.BeginEdit(True)
        dgv1.CurrentRow.Cells("Заказ").Value = TextBox1.Text
        dgv1.CurrentRow.Cells("Наименование").Value = TextBox2.Text
        dgv1.EndEdit()
 
 da.UpdateCommand = cmdBuilder.GetUpdateCommand
 da.Update(ds, ds.Tables(0).TableName)
 ds.AcceptChanges()
End Sub

Испробовал все доступные мне методы. Все как об стену.

P.S. Подразумеваю это может быть связано с событиями Validated и Validating для DataGridView (хз как, но остается грешить только на это)

P.P.S. МУЖИКИ, ВСЕХ С НАСТУПАЮЩИМ!
0
Миниатюры
Как вы делаете Update данных в БД (при использовании DataGridView, DataSet, DataAdapter)  
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.02.2012, 12:04
Ответы с готовыми решениями:

Волнует скорость DataSet и DataAdapter.Update
При использовании метода Update в базу данных вносятся изменения со всего DataSet'а или система...

Запись данных в базу данных mdb с использованием DataAdapter и DataSet
Попробовал сделать Update для таблицы контактов: private void Form1_Load(object sender,...

Обновление базы данных dataadapter.Update
знаю что таких тем было много но ни на одной из них я не нашел ответа на свой вопрос ...

Работа с Datagridview, Dataset, Update
Здравствуйте, помогите рзобраться как работать с DataSet Код DataSet detDataSet = new...

Пакетная передача обновлений (Insert) в базу данных посредством DataAdapter.Update
Здравствуйте, господа :yes: Кто-нибудь имел дело с пакетной передачей обновлений (а конкретно...

31
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
22.02.2012, 13:28  [ТС] 2
Ну или зайдем с другой стороны - как вы делаете Update данных в БД (при условии использования DataGridView, DataSet, DataAdapter...)?

Заранее спасибо.
0
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
24.02.2012, 06:01  [ТС] 3
Неужели никто не делает так?

В книгах тактично обходят этот вопрос. А вопрос то на самом деле бытовой...
0
gitarillo
732 / 532 / 47
Регистрация: 17.06.2010
Сообщений: 1,035
Записей в блоге: 1
24.02.2012, 09:51 4
Цитата Сообщение от Maden Посмотреть сообщение
как вы делаете Update данных в БД
SQL запросом. Все программно - и подключение, и наполнение грида и вся работа с ним
1
24.02.2012, 09:51
nio
5969 / 3375 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
24.02.2012, 10:01 5
теоретически все написано правильно, за исключением вот этой строки:
Цитата Сообщение от Maden Посмотреть сообщение
da.UpdateCommand = cmdBuilder.GetUpdateCommand
а ты проверял, сколько строк затронул метод Update?
каким способом ты проверяешь произошли или нет изменения?
1
serg42
120 / 102 / 7
Регистрация: 14.02.2010
Сообщений: 263
24.02.2012, 10:29 6
А зачем программно менять содержимое DGV, коли он привязан к данным? Работайте с BindingSource.
По ошибке х/з что сказать. Надо вскрытие производить, искать где косяк и почему. Раз не попадают в ДБ, значит строка не помечается как измененная, либо помечается, а потом что-то сбрасывает метку.
0
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
24.02.2012, 11:12  [ТС] 7
Ну тут название темы модераторы подкорректировали. Как делать подключение и тому подобное я в курсе, и делаю сам все это в коде. Меня интересует именно Апдейт ДатаСета из ДатаГридВью.
0
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
24.02.2012, 11:30  [ТС] 8
Я исходил из тех соображений, что если Грид привязан к ДатаСету, то и изменения из грида попадают в Датасет (опытным путем установлено). С bindingSource эксперементировал - но по мне он как пятое колесо.
Интересно просто, все-таки это моя ошибка или какой-то баг.
Вот приложу проект проверочный. Сами убедитесь.

Вариант 1 (рабочий):
[Загрузить БД] --> (выбрать строку) --> [Добавить] --> [Сохранить] --> [Загрузить БД] (просто чтобы перечитать данные)

Вариант 2 (НЕ работает):
[Загрузить БД] --> (выбрать строку) --> [Добавить и Сохранить] --> [Загрузить БД]
0
Вложения
Тип файла: rar WindowsApplication2.rar (132.6 Кб, 173 просмотров)
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
24.02.2012, 11:36  [ТС] 9
nio
Я проверял корректность составления АпдейтКоманды.
А сколько строк изменено проверял так:

vb.net
1
2
Dim kol as integer = da.Update(ds, ds.tables(0))
MessageBox.Show("Обновлено " & kol & " записей")
Изменения (при втором варианте) проходят через раз (при двойном нажатии на кнопку?)
0
nio
5969 / 3375 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
24.02.2012, 11:55 10
Maden, ну тогда проверяй перед вызовом UPDATE, есть ли твои данные в источнике
0
serg42
120 / 102 / 7
Регистрация: 14.02.2010
Сообщений: 263
24.02.2012, 12:15 11
Цитата Сообщение от Maden Посмотреть сообщение
Я исходил из тех соображений, что если Грид привязан к ДатаСету, то и изменения из грида попадают в Датасет (опытным путем установлено). С bindingSource эксперементировал - но по мне он как пятое колесо.
Тода и работайте напрямую с ДатаСетом, чего тревожить Грид-то?
0
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
24.02.2012, 17:01  [ТС] 12
Если работать напрямую с ДатаСетом - то мне надо определять какая строка выделена в гриде, находить ключ и потом выводить данные в форму.... что согласитесь намного дольше. Если не разберусь в этом вопросе - буду напрямую в ДатаСет ковыряться.

А кто-нибудь проверил тестовую прогу выше? Правильно хоть я говорю? А то, может, мой подход неверный.

P.S. Спасибо всем отвечающим.
0
serg42
120 / 102 / 7
Регистрация: 14.02.2010
Сообщений: 263
24.02.2012, 17:39 13
Цитата Сообщение от Maden Посмотреть сообщение
Если работать напрямую с ДатаСетом - то мне надо определять какая строка выделена в гриде, находить ключ и потом выводить данные в форму.... что согласитесь намного дольше.
А ничего не понял. Данные связаны "двусторонне", при изменении в гриде - изменяется таблица и наоборот.
Для вашего кода будет что-то вроде:
C#
1
2
3
4
5
6
7
8
9
DataRowView drv = (DataRowView) dgv1.CurrentRow.DataBoundItem;
DataRow row = (DataRow)drv.Row;
 
row.BeginEdit();
row["field"] = ".......";
.....
row.EndEdit();
 
......
0
_katon_
385 / 241 / 20
Регистрация: 03.10.2011
Сообщений: 1,003
24.02.2012, 17:49 14
У меня тоже были проблемы с гридом! Я их не решил, а посему "заковырял" датасет до победного конца. Язык был только "немного" другой! C# заместо VB. Грид я использовал только для чтения данных и отображения их на форме по двойному клику. Для записи я использовал TableUdapter с его методом Update. Если меня не устраивал стандартный Update, то писал свой (в дизайнере типизированного датасета это делать легко).
Если честно, то меня тоже немного удивило, что как-то уж очень замысловато все с этим DataGridViwe. До сих пор думаю, что удобнее всего (но не быстрее с точки зрения производительнсои) работать только гридом. До сих пор интересно ознакомится с кодом который не только добавит данные в грид, но и обновит этими данными базу. Интереснее всего как заставить грид обновить совой источник данных...
1
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
24.02.2012, 18:26  [ТС] 15
serg42
Поскольку связь двусторонняя - я и говорю хочу решить эту проблему, делаю аналогично - но не выходит. Мне уже не важно на каком языке будет написано - C# или VB - суть не изменится.

Я говорю, почему-то данные обновляются корректно только когда функции заполнения грида и обновления разделены (находятся в разных процедурах - скажем, на разных кнопках "Изменить" и "Сохранить"). Если их положить в одну функцию - то данные отображаются в гриде, но в ДатаСет не уходят...

_katon_
Кажется мне придется тоже ковырять ДатаСет, а не грид. А так - в обновлении ДатаСета из грида ничего особенного нет - все так же делается через da.update(ds)
0
serg42
120 / 102 / 7
Регистрация: 14.02.2010
Сообщений: 263
24.02.2012, 18:53 16
Что конкретно не выходит?
В ДатаСет они не уходят видимо потому, что должена вызываться функция типа RefreshEdit , или UpdateCellValue, или чё-нить в этом духе. Но я всё не рекомендую таким извращенным способом вносить данные в ДатаСет.
1
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
24.02.2012, 21:31  [ТС] 17
serg42
Я просто думал что кто-то кроме меня сталкивался с такой проблемой. Кажется, придется варганить что-нибудь с BindingSource или напрямую лезть в DataSet.

Может кто подскажет "типовой" вариант?
0
nio
5969 / 3375 / 335
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
24.02.2012, 21:43 18
Цитата Сообщение от Maden Посмотреть сообщение
Может кто подскажет "типовой" вариант?
Посмотри важные темы этого раздела
2
_katon_
385 / 241 / 20
Регистрация: 03.10.2011
Сообщений: 1,003
02.03.2012, 18:19 19
Я разобрался как обновлять данные из грида в базу при использовании типизированного датасета. Дело в том, что запись добавленная в грид моментально синхронизируется с myDataTable назначеной в качестве источника данных. А это означает, что вопрос стоит только в том, когда выполнить метод Update для адаптора.
Для типизированного датасета метода Update уже сгенерирован и перегружен для всех случаев, а это означает, что добавление/обнавление/удаление данных происходит одним и тем же способом:
C#
1
this.myTableAdapter.Update(myDataSet)
Т.е. датасет ковырять вообще бессмысленно и глупо.

Кроме этого если к гриду цеплять навигатор, то необходимо в качестве источника данных указывать BindignSource.
Maden, я думаю что основная проблемма это недопонимание принципов работы объектов связанных c гридом.
1
Maden
107 / 107 / 5
Регистрация: 14.01.2011
Сообщений: 130
02.03.2012, 19:57  [ТС] 20
_katon_
принципы я понимаю. Кроме того знаю различные подходы к обновлению данных.
Я лишь не понимаю что за баг это такой с гридом.

Если не трудно, скачай проект на 1й странице в моем посте - и убедись, как реализован один из подходов.

-------------------
Еще раз поясню что мне не понятно

Известно что если к гриду подцепить DataSet (или BindingSource, или впринципе - таблицу), то все изменения двусторонне направлены (изменяем грид -> меняется DataSet и наоборот (при выполенении DataAdapter.Update(ds))).

Утверждение верно? Верно.

Мне не понятно почему если на две кнопки поместить функции 1. Изменение грида 2. Апдейт - то все прекрасно работает. А вот если все это действие закрепить за одной кнопкой типа "Изменить и сохранить" - то ничего не работает (или работает через раз и вообще нестабильно)

...
0
02.03.2012, 19:57
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.03.2012, 19:57

Как правильно сделать update с посредством dataadapter
Всем привет! Возник вопрос. Есть в бд табличка CountryId - int (ключ + индексируемый столбец)...

Обновление данных в Datagridview из БД при использовании BackgroundWorker
Решил попробовать при обращении к базе использовать информационное окошко с текстом "Выполняется...

Не существует в текущем контексте dataAdapter и dataSet
try { string sql = "Select * From tovar"; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru