Страницы

Поиск по вопросам

суббота, 9 марта 2019 г.

Как сохранить таблицу из DataGridView в БД (MS Access)?

Каким образом можно сохранить таблицу, изменённую в DataGridView, в БД?
Отображаю таблицы так:
public void refreshTable() { string conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb"; OleDbConnection connection = new OleDbConnection(conStr); OleDbDataAdapter adapter = new OleDbDataAdapter();
connection.Open(); OleDbCommand command = new OleDbCommand("SELECT * FROM " + comboBox1.Text, connection); //в comboBox1 название таблицы
connection.Close();
adapter.SelectCommand = command; DataSet dataSet = new DataSet(); adapter.Fill(dataSet); dataGridView1.DataSource = dataSet.Tables[0]; adapter.Update(dataSet); }
Везде ссылаются на эту статью: http://tech.pro/tutorial/664/csharp-tutorial-binding-a-datagridview-to-a-database
Но я никак не пойму. Взял код оттуда:
private void saveButton_Click(object sender, EventArgs e) { string conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb"; OleDbConnection connection = new OleDbConnection(conStr); OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM " + comboBox1.Text, connection);
BindingSource bSource = new BindingSource(); DataTable dTable = new DataTable();
adapter.Fill(dTable); bSource.DataSource = dTable; dataGridView1.DataSource = bSource;
adapter.Update(dTable); }
Но он только выводит исходную таблицу из БД (что довольно очевидно). Что мне следует изменить в этом методе?
Примерно так выглядит добавление строк в таблицу:

После вызова метода через нажатие кнопки, 3 новые строки исчезают и, соответственно, не попадают в БД.
Обновление: кроме того, если я ввожу что-нибудь недопустимое (буквы в качестве ключа или даты), то получаю исключение, при вызове saveButton_Click.
Обновление: добавил в начале метода записи в БД:
connection.Open(); adapter.SelectCommand = new OleDbCommand("SELECT * FROM dataGridView1", connection); adapter.UpdateCommand = cBuilder.GetUpdateCommand(true); adapter.InsertCommand = cBuilder.GetInsertCommand(true); connection.Close();
Теперь при выполнении строки adapter.UpdateCommand = cBuilder.GetUpdateCommand(true); получаю ошибку о том, что требуется инициализировать свойство DataAdapter.SelectCommand. Хотя я, вроде как, прямо перед этим её инициализировал.


Ответ

Не дам полного ответа, так как очень давно не работал с winforms, но навскидку у вас в коде сразу две ошибки:
Вы создаете новый адаптер каждый раз при нажатии на кнопку, таким образом затирая все свои изменения, по уму этот код нужно перенести в Window_Load(). При создании адаптера создается только SelectCommand, а для связи с источником нужны еще UpdateCommand, InsertCommand и DeleteCommand. Их надо, либо создать ручками, либо если таблица не содержит связей с другими таблицами, можно воспользоваться OleDbCommandBuilder
UPD:
// должна быть для конкретного адаптера выполнена команда Fill(...) OleDbCommandBuilder cb = new OleDbCommandBuilder(adapter);
adapter.InsertCommand = cb.GetInsertCommand(); ... // прочие команды
Как то так, но я с адаптерами я не работал уже очень давно, поэтому вам лучше почитать, например здесь, правда там не OleDb*, но в принципе все аналогично.
UPD #2:
Добавлять команды в адаптер вы должны тоже в Window_Load сразу после
adapter.Fill(dTable);
Эта функция должна быть выполнена обязательно ДО, что бы адаптер смог получить схему для которой создает команды.
Насчет ошибки при вводе некорректных данных, абсолютно правильное поведение программы, поищите здесь на сайте были уже вопросы о валидации и инжекции кода , в общем это отдельная большая тема.
UPD #3:
Судя по сообщению, видимо нет. Там где вы делаете Update, поставте точку отладчика и посмотрите, чему равен InsertCommand, возможно вы в разных функциях используете разные адаптеры. Надо: сделать поле формы, в Window_Load - проинициализировать его, в Button_Click - вызвать функцию Update. А вы похоже в просто закинули ваш код в Window_Load - при выходе из которого адаптер просто уничтожается.
Ваш код должен выглядеть как то так:
public FormExemple : Form { protected string conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb"; protected OleDbConnection connection; protected OleDbDataAdapter adapter; ....
Window_Load() { connection = new OleDbConnection(conStr); ... adapter.Fill(dTable);
cb = new OleDbCommandBuilder(adapter); adapter.InsertCommand = cb.GetInsertCommand(); ... }
Button_Click() { ... adapter.Update(dTable) ... } }

Комментариев нет:

Отправить комментарий