C#. Учимся работать с MySQL



В этой статье мы рассмотрим взаимодействие с популярной СУБД «MySQL» из приложения на C#. К сожалению, в самом C# нет компонентов или классов для работы с MySQL, поэтому нам придется обратиться к общедоступному классу MySqlLib.

Что мы будем делать

В статье я не буду грузить теорией, а рассмотрю типичные операции (выборка, добавление, удаление, обновление), возникающие при работе с БД. Все эти операции я буду рассматривать на примере конкретного приложения. Как правило, для знакомства с БД пишут свой телефонный справочник (прим. редактора – да, все мы с этого начинаем). Мы не будем отступать от этой вековой традиции и тоже напишем свой простенький справочник. Итак, приступим.

Схема БД

Для начала нам надо создать саму БД, с которой потом будем работать из своего приложения. Чтобы сильно не заморачиваться, я предлагаю создать в БД всего одну таблицу. Назовем ее TablePhoneBook и подгоним ее под следующую структуру:
CREATE TABLE `TablePhoneBook` (
`idTablePhoneBook` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,//первичный ключ
`FM` VARCHAR(45),//фамилия
`IM` VARCHAR(45),//имя
`OT` VARCHAR(45),//отчество
`Phone` VARCHAR(45),//№ телефона
PRIMARY KEY(`idTablePhoneBook`)
).

Этой таблицы нам вполне достаточно для небольшого телефонного справочника. В будущем можно будет усовершенствовать проект. Например, если у абонентов несколько номеров, то можно выделить ФИО абонента в отдельную таблицу, а в эту писать его идентификатор и номер телефона.

Использование класса MySqlLib

Для использования класса MySQLLib нам понадобиться два файла: MySql.Data.dll и MySqlData.cs. Саму библиотеку закинем в папку, в которой будет храниться исполняемый файл нашей программы (у меня это «D:\VSProjects\MySQLTelBook\MySQLTelBook\bin\Debug»). Файл с программным кодом в папку, где лежат остальные исходники («D:\VSProjects\MySQLTelBook\MySQLTelBook»). Следующим шагом добавим библиотеку в наш проект. Делается это через «Project» -> «AddReference». Выполнив эту операцию, ты увидишь окно как на рисунке 1.


Рисунок 1. Подключаем библиотеку

В этом диалоге тебе нужно зайти в папку bin/Debug и выбрать MySql.Data.dll. Отлично, библиотеку подключили и теперь надо добавить к проекту файл MySqlData.cs. Для этого идем в меню Project->Add Existing Item и находим нужный файл в папке проекта. Последним подготовительным шагом будет подключение пространства имен
«using MySql.Data».

Вуаля! Теперь мы можем использовать в своем проекте данный класс. Все методы класса являются статическими, поэтому к ним обращаться, не создавая переменную класса.

Создаем интерфейс

Работать мы будем с обычным WinForms-приложением. Создай соответствующий проект и приготовься сотворить простенький интерфейс. Наше приложение будет состоять из 2-х окон. Первое окно - это главная форма программы, назовем ее MainForm. Я не сильно заморачивался с его оформлением и сделал максимально простой интерфейс (см. рисунок 2).


Рисунок 2. Главная форма будущего приложения

Вверху расположена группа TextBox’ов для ввода различных условий (фамилия, имя, отчество) выборки из базы. Сразу под ней расположена таблица (компонент DataGridView), в которую будет выводиться наш справочник, с учетом указанных пользователем фильтров.

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

Вторую форму назовем AddChangeForm. Она будет использоваться при добавлении/редактировании записи в телефонной книге. Мой вариант формы представлен на рисунке 3.


Рисунок 3. Дизайн форма AddChangeForm

TextBox’ы используются для ввода информации, а кнопки - для сохранения или отмены изменений. Теперь добавим свойство формы iIdRecord.
public partial class AddChangeForm : Form
{
public Int32 iIdRecord{get;set;}
public AddChangeForm()
{
InitializeComponent();
}
}

Оно будет хранить значение id-записи, которую мы редактируем или 0, если мы добавляем новые данные. Следующим шагом установим свойства DialogResult для обеих кнопок. У кнопки buttonOk (с текстом “OK”) сделать “OK”, а у buttonCancel соответственно Cancel. Это нам потребуется, когда мы будем обрабатывать результат вызова формы AddChangeForm.

Кодим

Медленно, но верно мы и добрались до кодинга. Первым делом напишем функцию выбора данных из БД. Ее код представлен в листинге 1.

Листинг 1. Выборка из БД
private void SelectDataFromDB()
{
///переменная,в которой содержится
///SQL-запрос на выборку
String sSQL = GetSQLString();
///строка подключения к БД
///Database-название БД MySQL
///Data Source-IP-адрес или имя компа,
///на котором крутится MySQL
///User ID-имя пользователя для подключения
///Password-он и в Африке password
String sConnectionString="Database=base;Data Source=localhost;User Id=root;Password=pass";
///в этой переменной будет содержаться рез-тат запроса
MySqlLib.MySqlData.MySqlExecuteData.MyResultData result = new MySqlLib.MySqlData.MySqlExecuteData.MyResultData();
///выполняем запрос, который возвращает результат
result = MySqlLib.MySqlData.MySqlExecuteData.SqlReturnDataset(sSQL, sConnectionString);
///если ошибок нет
if (result.HasError == false)
{
///очищаем таблицу для вывода результата
dataGridViewTable.Columns.Clear();
///заполняем таблицу на основе данных запроса
dataGridViewTable.DataSource = result.ResultData.DefaultView;
}
///если есть ошибка
else
{
///показываем ее в MessageBox'е
MessageBox.Show(result.ErrorText);
}
}

Я постарался снабдить код подробными комментариями, так что, думаю, тут все понятно. Единственное, нам надо описать функцию GetSQLString(). Ее код я привел в листинге 2.

Листинг 2. Функция GetSQLString()
private string GetSQLString()
{
///начинаем формировать запрос
///сначала подготавливаем общую информацию о выборке
///поля и таблицу для выборки
string sSQL = "SELECT idTablePhoneBook,FM,IM,OT,Phone FROM TablePhoneBook WHERE FM<>'' ";
///если поле textBoxFamily не пустое,то делаем выборку по полю FM
if (textBoxFamily.Text != "") sSQL += " AND FM LIKE '%" + textBoxFamily.Text+ "%'";
///если поле textBoxName не пустое,то делаем выборку по полю IM
if (textBoxName.Text != "") sSQL += " AND IM LIKE '%" + textBoxName.Text + "%'";
///если поле textBoxOt не пустое,то делаем выборку по полю OT
if (textBoxOt.Text != "") sSQL += " AND OT LIKE '%" + textBoxOt.Text + "%'";
///если поле textBoxTel не пустое,то делаем выборку по полю Phone
if (textBoxTel.Text != "") sSQL += " AND Phone LIKE '%" + textBoxTel.Text + "%'";
///делаем сотритровку по Фамилии
sSQL+=" ORDER BY FM";
return sSQL;
}

Теперь нам надо определиться на какие действия пользователя будем вызывать функцию SelectDataFromDB(). Я предлагаю делать это, когда пользователь только активирует форму (событие Activated), а так же вводит данные в текстовые поля в верхней части формы. Для этого кликаем по форме в месте, где нет других компонентов, и попадаем в окно кода.


Рисунок 4. Описываем событие Load главной формы

Здесь и пропишем вызов нашей функции SelectDataFromDB(). Вернемся в дизайнер формы. Щелкаем мышкой по TextBox с фамилией и в свойствах компонента выбираем события.


Рисунок 5. Рисунок 4. Выбираем события

Нас интересует Text_Changed, поэтому выбираем именно его. Установи на него выделении и увидишь выпадающий список, в котором нужно выбрать MainForm_Load. Теперь при вызове события TextChanged будет выполняться функция MainForm_Load, а в ней вызываться SelectDataFromDB().

Тоже самое сделаем для всех оставшихся TextBox’ов. Нам необходимо чтобы при изменении содержания каждого TextBox’а происходило обновление данных.

Добавление данных

Теперь рассмотрим процедуру добавления данных в БД. Для того чтобы добавить данные, пользователю требуется нажать кнопку “Добавить”. В ответ на это действие будет вызвана форма AddChangeForm с пустыми TextBox’ами. После того, как пользователь заполнит все поля и нажмет кнопку “ОК” нам потребуется составить SQL-запрос на вставку данных в БД и выполнить его. После этого закроем форму AddChangeForm и обновим содержимое главной формы.

Алгоритм понятен, приступаем к реализации. Кликаем два раза на кнопку buttonAdd и в обработчике события пишем код из листинга 3.

Листинг 3. Добавление данных
private void buttonAdd_Click(object sender, EventArgs e)
{
///создаем объект формы добавления записи
AddChangeForm addForm = new AddChangeForm();
///т.к. мы СОЗДАЕМ,то св-во iIdRecord нулевое
addForm.iIdRecord = 0;
///показываем форму в режиме диалога
if (addForm.ShowDialog() == DialogResult.OK)
///если нажали ОК (именно для этого мы
///и заполняли св-ва кнопок DialogResult),
///значит обновляем содержимое таблицы
SelectDataFromDB();
}

В нем мы создали экземпляр формы AddChangeForm и вызвали ее в модальном режиме. Теперь приступаем к работе с формой добавления записи. Дважды щелкаем по кнопке buttonOK и опять напишем немного кода. Только теперь из листинга 4.

Листинг 4. Соединение с БД и выполнение запроса
private void buttonOK_Click(object sender, EventArgs e)
{
string sSQL="";
///формируем строку подключения к MySQL
String sConnectionString="Database=test;Data Source=localhost;User Id=root;Password=1";
///если поле iIdRecord равно 0,
///значит добавляем запись
if (iIdRecord==0)
///формируем запрос на добавление
sSQL = GetInsertSQL();
else
///иначе редактируем
///и формируем запрос на редактирование
sSQL = GetUpdateSQL();
///выполняем SQL-запрос
MySqlLib.MySqlData.MySqlExecute.SqlNoneQuery(sSQL, sConnectionString);
}

В этом листинге используется функция GetInsertSQL(). Она на основе введенных данных возвращает нам SQL-запрос для вставки данных. Ее код ищи в пятом листинге.

Листинг 5. Функция вставки данных в SQL
private string GetInsertSQL()
{
string sSQL = "INSERT INTO TablePhoneBook (FM,IM,OT,Phone) VALUES (";
sSQL += "'"+textBoxFamily.Text+"',";
sSQL += "'" + textBoxName.Text + "',";
sSQL += "'" + textBoxOt.Text + "',";
sSQL += "'" + textBoxTel.Text + "')";
return sSQL;
}

После нажатия кнопки buttonOK происходит закрытие формы AddChangeForm и вызов функции MainForm главной формы, что приводит к обновлению содержания таблицы.

Редактирование данных

Процесс редактирования очень похож на добавление данных. Разница в том, что при вызове формы AddChangeForm ее поля заполняются значениями редактируемой записи. И запрос выполняется не на добавление, а на обновление. Попробуем реализовать процесс на практике. Дважды щелкаем на кнопке “Редактировать” и набиваем код из листинга 6.

Листинг 6. Редактирование записей
///если выделена не пустая ячейка
if (dataGridViewTable.CurrentCell != null && dataGridViewTable.CurrentCell.ColumnIndex == Innocent
{
///создаем объект формы добавления записи
AddChangeForm addForm = new AddChangeForm();
///т.к. мы ОБНОВЛЯЕМ,то заполняем св-во iIdRecord
addForm.iIdRecord = Convert.ToInt32(dataGridViewTable.CurrentCell.Value);
///показываем форму в режиме диалога
if (addForm.ShowDialog() == DialogResult.OK)
///если нажали ОК (именно для этого мы
///и заполняли св-ва кнопок DialogResult),
///значит обновляем содержимое таблицы
SelectDataFromDB();
}

В результате выполнения кода из листинга №6 перед нами откроется форма AddChangeForm с заполненными полями. Сохранение изменений будет происходить по кнопке buttonOK. Когда я описывал код для добавления записи, я уже рассмотрел вариант обновления записи, в этих строках
else
///иначе редактируем
///и формируем запрос на редактирование
sSQL = GetUpdateSQL();

Удаление данных

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

Листинг 7. Удаление данных
private void buttonDel_Click(object sender, EventArgs e)
{
///если выделена не пустая ячейка
if (dataGridViewTable.CurrentCell != null && dataGridViewTable.CurrentCell.ColumnIndex==0)
{
if (MessageBox.Show("Вы уверены,что хотите удалить запись под № " + dataGridViewTable.CurrentCell.Value.ToString(),
"Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.OK)
{
///формируем строку подключения к MySQL
String sConnectionString = "Database=test;Data Source=localhost;User Id=root;Password=1";
///выполняем SQL-запрос
MySqlLib.MySqlData.MySqlExecute.SqlNoneQuery("DELETE FROM TablePhoneBook WHERE idTablePhoneBook=" + dataGridViewTable.CurrentCell.Value.ToString(), sConnectionString);
SelectDataFromDB();
}
}
}

Заключение

Ну, вот вроде бы и все. Мы рассмотрели простой класс для работы с MySQL из C#, а также набросали простенький примерчик в виде телефонной книжки. Надеюсь, было не очень скучно, и материал тебе оказался полезным. Если есть вопросы – пиши мне на email. Буду рад помочь. Удачи!

Written by: Евгений Шапиро
E-mail: zheka@xakep.ru

Комментарии

18 комментария(ев)
аватар: DjadjaSem
DjadjaSem
Дата: ЧТ, 07/04/2011 - 12:28
Звание: Наблюдатель
Сообщений: 4

А где взять этот злосчастный MySqlData.cs ??
Sad

аватар: J.T.
J.T.
Дата: Втр, 02/08/2011 - 05:01
Звание: Энтузиаст
Сообщений: 115

Погуглить можно Wink

аватар: Lord_of_fear
Lord_of_fear
Дата: ЧТ, 07/04/2011 - 14:48
Звание: Мастер
Сообщений: 2213

2DjadjaSem
Самый простой вариант - задать автору статьи вопрос по почте Smile

аватар: DjadjaSem
DjadjaSem
Дата: ЧТ, 07/04/2011 - 15:05
Звание: Наблюдатель
Сообщений: 4

нашел его в другой статье, с ним все компилируется: ]]>http://kbss.ru/blog/lang_c_sharp/96.html]]>

аватар: DjadjaSem
DjadjaSem
Дата: ЧТ, 07/04/2011 - 15:07
Звание: Наблюдатель
Сообщений: 4

А еще интересует листинг функции GetUpdateSQL. Дело в том что мне необходимо менять статус сообщения при прочтении, и делать это я собираюсь при открытии сообщения, по его id. Помогите кто сведущ! Извени за назойливость "Автор":)

Добавление, изменение и удаление не работают! Я кривой, или все такие?

аватар: jimmyjonezz
jimmyjonezz
Дата: ЧТ, 07/04/2011 - 19:33
Звание: Мастер
Сообщений: 2468

Советую вопросы задавать на форуме или писать непосредственно автору статьи.

аватар: DjadjaSem
DjadjaSem
Дата: ЧТ, 07/04/2011 - 19:43
Звание: Наблюдатель
Сообщений: 4

Прошу прощения. это я кривой, скобки не закрыл

аватар: Zhenya
Zhenya
Дата: ЧТ, 26/05/2011 - 17:29
Звание: Наблюдатель
Сообщений: 14

листинг GetUpdateSQL
private string GetUpdateSQL()
{
StringBuilder sSQL =new StringBuilder("UPDATE TablePhoneBook SET ");
sSQL.Append("FM='").Append(textBoxFamily.Text).Append("',");
sSQL.Append("IM='").Append(textBoxName.Text).Append("',");
sSQL.Append("OT='").Append(textBoxOt.Text).Append("',");
sSQL.Append("Phone='").Append(textBoxPhone.Text).Append("'");
sSQL.Append(" WHERE idTablePhoneBook=").Append(iIdRecord.ToString());
return sSQL.ToString();
}

аватар: NeReformator
NeReformator
Дата: СР, 14/03/2012 - 05:34
Звание: Наблюдатель
Сообщений: 2

Доброго времени суток...
Не давно начал работать с mysql.
Ваш пример оказался для меня очень полезным...
Но возник один вопрос. Скажите а можно когда мы выбираем запись в dataGridViewTable после чего нажимаем кнопку "изменить" в появившемся окне поля textbox были заполнены данными из той строки dataGridViewTable в которую мы хотим занести измененные данные.
Заранее благодарю.
Если можно то приведите пример ввиде кода для вашей статьи...

аватар: inst86
inst86
Дата: СР, 21/03/2012 - 16:58
Звание: Наблюдатель
Сообщений: 2

можно, в датагридвью есть свойство SelectedRows , передает индекс строки, дальше просто с нужной ячейки вытаскиваем то что нам надо
вечером дома буду детальнее напишу