Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.68/76: Рейтинг темы: голосов - 76, средняя оценка - 4.68
 Аватар для Maden
111 / 111 / 5
Регистрация: 14.01.2011
Сообщений: 130

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

22.02.2012, 12:04. Показов 16383. Ответов 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. МУЖИКИ, ВСЕХ С НАСТУПАЮЩИМ!
Миниатюры
Как вы делаете Update данных в БД (при использовании DataGridView, DataSet, DataAdapter)  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.02.2012, 12:04
Ответы с готовыми решениями:

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

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

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

31
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
03.03.2012, 02:11
Студворк — интернет-сервис помощи студентам
я согласен с твоим мнением о том, что это связано с порядком вызова внутренних функций. Вроде как строка и была изменена, но её статус Row.State не изменился, а именно он влияет на адаптер.
Отслеживать их бессполезно так как мелкософт не гарантиртирует прямой порядок их вызова. Да, например, Validated после Validating но форматеры ендэдиторы и прочие могут быть в каком угодно порядке по отношению к ним.
Лично я бы в данном примере при изменениях в форме к датагриду делел бы прямой запрос к БД и паралельно в ДатаСет, так как адаптер проходит все строки таблицы, а это лишние действия ни к чему.

к тому же частенько приходится вместо дата адатпера писать свои более гибкие запросы и в цикле пройдясь по строкам грида или связанной таблицы в зависимости от данных использовать различные запросы-команды.
0
 Аватар для _katon_
414 / 265 / 25
Регистрация: 03.10.2011
Сообщений: 1,094
03.03.2012, 04:08
Mдя! Реально беда! Скачал проект, попробовал.. Думаю - баг))
0
 Аватар для Maden
111 / 111 / 5
Регистрация: 14.01.2011
Сообщений: 130
03.03.2012, 09:29  [ТС]
_katon_
Вот и я про тоже. Считай, такой простой способ и не работает. Может тут какие-то тонкости есть...
А в книгах во всех (и для VB и для C#) тактично так обходят этот вопрос, аж смешно...


_katon_, не хочу показаться дилетантом, но может приведешь пример кода которым ты пользуешься для отображения изменений в гриде и апдейта источника данных. Заранее спасибо.
0
 Аватар для nio
6050 / 3460 / 336
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
03.03.2012, 10:21
Maden, вопросом этим мало кто задается потому, что привязка программной вставки - это кривой способ. Программное изменение должно производится непосредственно в источник (об этом тебе еще на первой странице сказали), графический интерфейс предназначен для работы пользователя. Так работают профессионалы. Завтра может понадобиться использовать для отображения другой контрол, и вся логика твоей программы рухнет, придется сидеть и писать все заново.
2
 Аватар для _katon_
414 / 265 / 25
Регистрация: 03.10.2011
Сообщений: 1,094
03.03.2012, 21:52
Иногда необходимо выполнять программную вставку, когда контрол не реализует функциональность для заданного случая.
Пример: Когда грид только для чтения и доступ к данным осуществляется через карточку интерфейсного ввода данных.
Согласен с Nio - в грид данные лучше не вставлять (да и как мы с тобой убедились еще и невозомжно))) ). Я вставлял данные в DataTable и тогда у меня все работало. Но, вместе с тем, есть еще получение данных из грида (ведь выделяется запись для обновления именно там!) и вот эту часть мне при смене контрола точно придется переписывать.
Тем не менее как по другому быть в такой ситуации я не знаю...

По поводу кода...
Вот каким образом у меня осуществлялся Update.
1. Получение данных из грида (получение выделенной записи)
C#
1
2
3
4
5
6
7
       DataGridViewSelectedCellCollection DGVCell = DGV.SelectedCells;
                    dgvc = DGVCell[0];
                    dgvr = dgvc.OwningRow;
 
                    LicensorID = int.Parse(dgvr.Cells[1].Value.ToString());
                    tbName.Text = dgvr.Cells[0].Value.ToString();
                    tbDescription.Text = dgvr.Cells[2].Value.ToString();
2. Вот так я находил данные в таблице (по ID полученному из грида нахожу запись в таблице)
C#
1
2
3
       DataRow row = Dataset.tbl_Licensor.FindByLicensorID(LicensorID);
                    row["Name"] = tbName.Text;
                    row["Description"] = tbDescription.Text;
3. Ну и естественно сохранение в БД (это самое простое)
C#
1
this.tbl_LicensorTableAdapter.Update(this.tAXINSPECTIONDataSet1);
Тут пропущены некоторые определения, но я думаю что и так понятны классы объектов (выдирал куски из кода).

Если грид редактируемый, то достаточно пункта 3 ))).
Первоначально я делал вставку в грид и у меня из этого ничего не вышло (также как и у тебя))) ). Т.е. да он вставлял, да в таблице данные были, но сохранить их было невозможно.

И еще вспомнил один интригующий момент! Если я выполнял обновление два раза подряд, то текущая измененная запись не сохранялась, а зато пердыдущая - да!
1
 Аватар для Maden
111 / 111 / 5
Регистрация: 14.01.2011
Сообщений: 130
03.03.2012, 22:37  [ТС]
Цитата Сообщение от _katon_ Посмотреть сообщение
И еще вспомнил один интригующий момент! Если я выполнял обновление два раза подряд, то текущая измененная запись не сохранялась, а зато пердыдущая - да!
_katon_, да, я такое тоже заметил. Кстати, еще заметил - если выполнять редактирование прямо в гриде - тоже все замечательно работает.
Спасибо за пример кода.

nio, согласен с тобой полностью. Буду копать в том направлении тогда.


P.S. Спасибо за ваши советы!
0
 Аватар для Maden
111 / 111 / 5
Регистрация: 14.01.2011
Сообщений: 130
06.03.2012, 07:42  [ТС]
Вообщем подвожу итог своеобразный. Бороться с гридом как с ветрянной мельницей - занятие неблагодарное. Поэтому, по Вашему совету пошел по другому пути, описанному в том числе и в MSDN (ссылка на оригинал)

Применительно к VB: листинги выглядят так:

VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
' обновление записи в источнике данных
                        Dim curID As Integer
                        curID = DataGridView1.CurrentRow.Cells("Код").Value
 
                        Dim tblDocs As DataTable
                        tblDocs = ds.Tables("Docs")
 
                        Dim drCurrent As DataRow
                        drCurrent = tblDocs.NewRow
 
                        drCurrent = tblDocs.Rows.Find(curID)
                        drCurrent.BeginEdit()
 
                        drCurrent("Заказ") = TextBox1.Text
                        drCurrent("Обозначение") = TextBox2.Text
                        drCurrent("Наименование") = TextBox3.Text
 
                        drCurrent.EndEdit()
                        da.Update(.ds, "Docs")
Вывод один - надо работать с объектом DataRow

Всем спасибо за советы и участие.
3
124 / 106 / 7
Регистрация: 14.02.2010
Сообщений: 263
06.03.2012, 17:09
Я писал выше как получить DataRow непосредственно из текущей строки грида, не используя поиск по полю.
0
 Аватар для Maden
111 / 111 / 5
Регистрация: 14.01.2011
Сообщений: 130
06.03.2012, 18:57  [ТС]
serg42, это вот этот вариант?

C#
1
2
3
4
5
6
7
DataRowView drv = (DataRowView) dgv1.CurrentRow.DataBoundItem;
DataRow row = (DataRow)drv.Row;
 
row.BeginEdit();
row["field"] = ".......";
.....
row.EndEdit();
0
124 / 106 / 7
Регистрация: 14.02.2010
Сообщений: 263
06.03.2012, 21:30
угу .
1
0 / 0 / 0
Регистрация: 18.05.2015
Сообщений: 1
28.06.2015, 12:39
Добрый день! Столкнулся с точно такой же проблемой! Похоже это баг. Пробую подписать на событие 2 разные функции:
C#
1
dataGridView1.CellEndEdit += dataGridView1_CellEndEdit; dataGridView1.CellEndEdit += dataGridView1_CancelEdit;
, они вызываются последовательно, но и это не помогает! Данные записываются только после изменения/добавления новой строки. В этот момент в бд access записывается предыдущая строка. Кто то решил проблему?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void dataGridView1_CancelEdit(object sender, DataGridViewCellEventArgs e)
        {
 
            da.Update(dataSet1.Tables[0]);
            dataSet1.AcceptChanges();
        }
        
        void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 
        {
                            var dgv = sender as DataGridView;
                            if (dgv == null)
                                return;
 
                            var row = dgv.Rows[e.RowIndex];
                                row.Cells["photoDB"].Value = "Посмотреть";
                                dataGridView1.EndEdit();
                           }
Добавлено через 3 минуты
Та же проблема! Маюсь второй день! Подписываю на событие 2 разные функции:
C#
1
dataGridView1.CellEndEdit += dataGridView1_CellEndEdit; dataGridView1.CellEndEdit += dataGridView1_CancelEdit;
, они вызываются последовательно, но и это не помогает! Данные записываются только после изменения/добавления новой строки. В этот момент в бд access записывается предыдущая строка. Кто то решил проблему?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void dataGridView1_CancelEdit(object sender, DataGridViewCellEventArgs e)
        {
 
            da.Update(dataSet1.Tables[0]);
            dataSet1.AcceptChanges();
        }
        
        void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 
        {
                            var dgv = sender as DataGridView;
                            if (dgv == null)
                                return;
 
                            var row = dgv.Rows[e.RowIndex];
                                row.Cells["photoDB"].Value = "Посмотреть";
                                dataGridView1.EndEdit();
                           }
0
 Аватар для nio
6050 / 3460 / 336
Регистрация: 14.06.2009
Сообщений: 8,136
Записей в блоге: 2
30.06.2015, 10:11
Цитата Сообщение от EvgenKos Посмотреть сообщение
они вызываются последовательно, но и это не помогает!
тут проблема заключается в следующем - пока ячейка находится в режиме редактирования, изменённых данных в источнике не будет.
Ячейка выходит из режима редактирования в трёх случаях: потеря фокуса, нажатие Enter, нажатие Esc. В последнем случае изменения отменяются, т.е. данные в источнике не изменятся.
Есть ещё одна интересная особенность: если источник присоединён к dgv напрямую, то для "закрепления" изменений, должен измениться не только фокус ячейки но и строки, т.е. нужно тупо переставить курсор на другую строку. Но оптимально использовать связку с источником через контрол BindingSource, для которого перед сохранением можно вызвать метод EndEdit (тогда не нужно будет переводить фокус на другую строку и ячейку).
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.06.2015, 10:11

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru