Создание объектов OleDbCommand для передачи изменений в базу данных
Для взаимодействия с базой данных Microsoft Access нам потребуется настроить объекты OleDbCommand. Создайте новое Windows-приложение и назовите его "VisualAllOleDbCommands". Визуальная часть его создания будет совпадать с описанием разработки приложения VisualAllSqlCommands, за исключением, пожалуй, приставки "OleDb" в названиях объектов. Ключевым моментом здесь является синтаксис SQL-запросов - поставщик OleDb не поддерживает названия параметров типа "@Имя_параметра". Вместо этого используется знак вопроса - "?". С учетом этого правила запрос объекта myInsertCommand будет выглядеть так:
INSERT INTO Туристы (Фамилия, Имя, Отчество) VALUES (?, ?, ?)
Здесь мы убрали возможность вставки значения поля "Кодтуриста", поскольку в самой базе данных Microsoft Access значения этого поля подставляются автоматически7).
Немного сложнее будет устроена конструкция объекта myUpdate Command. Мы можем просто заменить значения параметров на символы вопроса:
UPDATE Туристы SET Кодтуриста = ?, Имя = ?, Отчество = ?, Фамилия = ? WHERE (Кодтуриста = ?)
Но тогда этот запрос допускает изменение значения поля "Кодтуриста", что приводит к ошибке (рис. 12.40):
увеличить изображение
Рис. 12.40. Неверный запрос объекта myUpdateCommand и связанное с ним сообщение об ошибке
Следовательно, наше приложение также не должно предоставлять возможность обновления значения поля "Кодтуриста":
UPDATE Туристы SET Имя = ?, Отчество = ?, Фамилия = ? WHERE (Кодтуриста = ?)
Аналогично, в запросе объекта myDeleteCommand убираем возможность удаления отдельного значения поля "Кодтуриста":
DELETE FROM Туристы WHERE (Фамилия = ?) OR (Имя = ?) OR (Отчество = ?)
Наконец, запрос объекта mySelectCommand, не содержащий параметров, будет иметь самый обычный вид:
SELECT * FROM Туристы
Код приложения также будет совпадать, за исключением префиксов в названиях объектов.
В программном обеспечении к курсу вы найдете приложение VisualAll OleDbCommands (Code\Glava6\VisualAllOleDbCommands).
Нетрудно создать аналогичное приложение без применения визуальных средств Visual Studio .NET. Создайте новое приложение и назовите его "ProgrammAllOleDbCommands". Перетаскиваем на форму элемент управления DataGrid, его свойству Dock устанавливаем значение "Fill". Подключаем пространство имен для работы с базой данных:
using System.Data.OleDb;
В классе формы создаем строку подключения, объекты DataSet и DataAdapter:
string connectionString = @"Provider=""Microsoft.Jet.OLEDB.4.0" ";Data Source=""D:\Uchebnik\Code\Glava3\BDTur_firm2.mdb" ";User ID=Admin;Jet OLEDB:Encrypt Database=False"; DataSet dsTourists; OleDbDataAdapter dataAdapter;
В конструкторе формы создаем все объекты ADO .NET:
public Form1() { InitializeComponent(); OleDbConnection conn = new OleDbConnection(); conn.ConnectionString = connectionString; OleDbCommand mySelectCommand = conn.CreateCommand(); mySelectCommand.CommandText = "SELECT * FROM Туристы"; dataAdapter = new OleDbDataAdapter(); dataAdapter.SelectCommand = mySelectCommand; dsTourists = new DataSet(); dataAdapter.Fill(dsTourists); dataGrid1.DataSource = dsTourists.Tables[0].DefaultView; //InsertCommand OleDbCommand myInsertCommand = conn.CreateCommand(); myInsertCommand.CommandText = "INSERT INTO Туристы (Фамилия, Имя, Отчество) VALUES (?, ?, ?)"; myInsertCommand.Parameters.Add("@Фамилия", OleDbType.VarWChar, 50, "Фамилия"); myInsertCommand.Parameters.Add("@Имя", OleDbType.VarWChar, 50, "Имя"); myInsertCommand.Parameters.Add("@Отчество", OleDbType.VarWChar, 50, "Отчество"); dataAdapter.InsertCommand = myInsertCommand; //UpdateCommand OleDbCommand myUpdateCommand = conn.CreateCommand(); myUpdateCommand.CommandText = "UPDATE Туристы SET Имя = ?, Отчество = ?, Фамилия = ? WHERE (Кодтуриста = ?)"; myUpdateCommand.Parameters.Add("@Имя", OleDbType.VarWChar, 50, "Имя"); myUpdateCommand.Parameters.Add("@Отчество", OleDbType.VarWChar, 50, "Отчество"); myUpdateCommand.Parameters.Add("@Фамилия", OleDbType.VarWChar, 50, "Фамилия"); myUpdateCommand.Parameters.Add(new OleDbParameter("@Кодтуриста", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Кодтуриста", System.Data.DataRowVersion.Original, null)); dataAdapter.UpdateCommand = myUpdateCommand; //DeleteCommand OleDbCommand myDeleteCommand = conn.CreateCommand(); myDeleteCommand.CommandText = "DELETE FROM Туристы WHERE (Фамилия = ?) OR (Имя = ?) OR (Отчество = ?)"; myDeleteCommand.Parameters.Add("@Фамилия", OleDbType.VarWChar, 50, "Фамилия"); myDeleteCommand.Parameters.Add("@Имя", OleDbType.VarWChar, 50, "Имя"); myDeleteCommand.Parameters.Add("@Отчество", OleDbType.VarWChar, 50, "Отчество"); dataAdapter.DeleteCommand = myDeleteCommand; }
В событии Closing формы передаем изменения в базу данных:
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e) { try { if (dsTourists.HasChanges()) { dataAdapter.Update(dsTourists); } } catch(Exception ex) { MessageBox.Show(ex.ToString()); } }
Запускаем приложение. Мы снова можем добавлять, изменять и удалять записи.
В программном обеспечении к курсу вы найдете приложение Programm AllOleDbCommands (Code\Glava6\ProgrammAllOleDbCommands).
При добавлении параметра "@Кодтуриста" в объект Update Command мы воспользовались конструктором OleDbParameter. В сравнении с методом Add набора OleDbParameterCollection (которым мы пользовались ранее), он предоставляет возможность задания большего количества свойств (рис. 12.41):
увеличить изображение
Рис. 12.41. Метод Add набора OleDbParameterCollection и конструктор new OleDbParameter
В таблице 12.3 приводится описание свойств конструктора.
parameterName | Название параметра. Например, "@Кодтуриста" или "Original_Кодтуриста" |
dbType | Тип данных параметра |
direction | Значение перечисления ParameterDirection, определяющее, является ли параметр входным, выходным, смешанным или возвращающим значение |
isNullable | Определение, может ли параметр иметь значения null |
precision | Точность числового параметра. Задается количеством знаков после запятой. Для нечисловых параметров это значение равно 0 |
scale | Шкала - общее число знаков числового параметра |
size | Размер параметра |
sourceColumn | Источник данных - название поля (столбца) в объекте DataSet или DataTable |
sourceVersion | Значение перечисления DataRowVersion, указывающее на версию передаваемых записей |
value | Значение параметра |
В окне редактора OleDbParameter Collection Editor мы видим параметр "Original_Кодтуриста" с определенными свойствами (рис. 12.42):
Рис. 12.42. Параметр "Original_Кодтуриста"
Переходим в код формы, раскрываем область Windows Form Designer generated code - для параметра "Original_Кодтуриста" среда сгенерировала код, применив конструктор OleDbParameter:
// // myUpdateCommand // ... this.myUpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter ("Original_Кодтуриста", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Кодтуриста", System.Data.DataRowVersion.Original, null));
В приложении ProgrammAllOleDbCommands для задания параметра "@Кодтуриста" мы применили этот же код, убрав определение пространства имен:
//UpdateCommand ... myUpdateCommand.Parameters.Add(new OleDbParameter("@Кодтуриста", System.Data.OleDb.OleDbType.Integer, 0, System.Data.ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "Кодтуриста", System.Data.DataRowVersion.Original, null));
Конструктор SqlParameter обладает аналогичной структурой и свойствами.
Здесь и далее под названием "DataAdapter" будут подразумеваться как OleDbDataAdapter, так и SqlDataAdapter.
2)
На этой странице очень часто встречается слово "конструктор" - не спутайте конструктор объекта DataAdapter с конструктором формы, который имеет вид: public Form1() {//Содержимое конструктора формы}
3)
Здесь и далее будут применяться названия на кириллице. Это сделано для наглядности - в реальных приложениях следует использовать латинские буквы.
4)
Или базы данных "Northwind".
5)
Как вы помните, свойство "AllowDBNull" объекта DataColumn определяет возможность пустых значений: DataColumn myColumn; DataColumn dcmyColumn = dtMyTable.Columns.Add("Название", typeof(Int32)); dcmyColumn.Unique = true; dcmyColumn.AllowDBNull = false;
6)
Метод EndCurrentEdit объекта CurrencyManager также позволяет справиться с этой задачей.
7)
Для этого поля установлен тип данных "счетчик". Это означает, что уникальные значения формируются автоматически в порядке возрастания - см. первую лекцию.