Класс для работы с базой данных (на примере MySQL)

В этой публикации я приведу пример более совершенного класса для работы с базой данных, нежели приводил ранее в этой публикации. Смысл как и прежде в минимизации кода и приведения его (кода) в более удобочитаемый вид.
В примере ниже, в отличие от предыдущего, в отдельном классе реализованы не только методы выполняющие запросы типа (Scalar и NonQuery) но и метод возвращающий набор данных в DataTable. При этом продумана обработка исключительных ситуаций.

Привожу код как есть, он весь прокомментирован, на столько на сколько это необходимо для понимания.

Сам класс:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data;
using System.Data;

namespace MySqlLib
{
    /// <summary>
    /// Набор компонент для простой работы с MySQL базой данных.
    /// </summary>
    public class MySqlData
    {

        /// <summary>
        /// Методы реализующие выполнение запросов с возвращением одного параметра либо без параметров вовсе.
        /// </summary>
        public class MySqlExecute
        {

            /// <summary>
            /// Возвращаемый набор данных.
            /// </summary>
            public class MyResult
            {
                /// <summary>
                /// Возвращает результат запроса.
                /// </summary>
                public string ResultText;
                /// <summary>
                /// Возвращает True - если произошла ошибка.
                /// </summary>
                public string ErrorText;
                /// <summary>
                /// Возвращает текст ошибки.
                /// </summary>
                public bool HasError;
            }

            /// <summary>
            /// Для выполнения запросов к MySQL с возвращением 1 параметра.
            /// </summary>
            /// <param name="sql">Текст запроса к базе данных</param>
            /// <param name="connection">Строка подключения к базе данных</param>
            /// <returns>Возвращает значение при успешном выполнении запроса, текст ошибки - при ошибке.</returns>
            public static MyResult SqlScalar(string sql, string connection)
            {
                MyResult result = new MyResult();
                try
                {
                    MySql.Data.MySqlClient.MySqlConnection connRC = new MySql.Data.MySqlClient.MySqlConnection(connection);
                    MySql.Data.MySqlClient.MySqlCommand commRC = new MySql.Data.MySqlClient.MySqlCommand(sql, connRC);
                    connRC.Open();
                    try
                    {
                        result.ResultText = commRC.ExecuteScalar().ToString();
                        result.HasError = false;
                    }
                    catch (Exception ex)
                    {
                        result.ErrorText = ex.Message;
                        result.HasError = true;
                    }
                    connRC.Close();
                }
                catch (Exception ex)//Этот эксепшн на случай отсутствия соединения с сервером.
                {
                    result.ErrorText = ex.Message;
                    result.HasError = true;
                }
                return result;
            }


            /// <summary>
            /// Для выполнения запросов к MySQL без возвращения параметров.
            /// </summary>
            /// <param name="sql">Текст запроса к базе данных</param>
            /// <param name="connection">Строка подключения к базе данных</param>
            /// <returns>Возвращает True - ошибка или False - выполнено успешно.</returns>
            public static MyResult SqlNoneQuery(string sql, string connection)
            {
                MyResult result = new MyResult();
                try
                {
                    MySql.Data.MySqlClient.MySqlConnection connRC = new MySql.Data.MySqlClient.MySqlConnection(connection);
                    MySql.Data.MySqlClient.MySqlCommand commRC = new MySql.Data.MySqlClient.MySqlCommand(sql, connRC);
                    connRC.Open();
                    try
                    {
                        commRC.ExecuteNonQuery();
                        result.HasError = false;
                    }
                    catch (Exception ex)
                    {
                        result.ErrorText = ex.Message;
                        result.HasError = true; 
                    }
                    connRC.Close();
                }
                catch (Exception ex)//Этот эксепшн на случай отсутствия соединения с сервером.
                {
                    result.ErrorText = ex.Message;
                    result.HasError = true;
                }
                return result;
            }
             
        }

        /// <summary>
        /// Методы реализующие выполнение запросов с возвращением набора данных.
        /// </summary>
        public class MySqlExecuteData
        {
            /// <summary>
            /// Возвращаемый набор данных.
            /// </summary>
            public class MyResultData
            {
                /// <summary>
                /// Возвращает результат запроса.
                /// </summary>
                public DataTable ResultData;
                /// <summary>
                /// Возвращает True - если произошла ошибка.
                /// </summary>
                public string ErrorText;
                /// <summary>
                /// Возвращает текст ошибки.
                /// </summary>
                public bool HasError;
            }


            /// <summary>
            /// Выполняет запрос выборки набора строк.
            /// </summary>
            /// <param name="sql">Текст запроса к базе данных</param>
            /// <param name="connection">Строка подключения к базе данных</param>
            /// <returns>Возвращает набор строк в DataSet.</returns>
            public static MyResultData SqlReturnDataset(string sql, string connection)
            {
                MyResultData result = new MyResultData();
                try
                {
                    MySql.Data.MySqlClient.MySqlConnection connRC = new MySql.Data.MySqlClient.MySqlConnection(connection);
                    MySql.Data.MySqlClient.MySqlCommand commRC = new MySql.Data.MySqlClient.MySqlCommand(sql, connRC);
                    connRC.Open();

                    try
                    {
                        MySql.Data.MySqlClient.MySqlDataAdapter AdapterP = new MySql.Data.MySqlClient.MySqlDataAdapter();
                        AdapterP.SelectCommand = commRC;
                        DataSet ds1 = new DataSet();
                        AdapterP.Fill(ds1);
                        result.ResultData = ds1.Tables[0];
                    }
                    catch (Exception ex)
                    {
                        result.HasError = true;
                        result.ErrorText = ex.Message;
                    }
                    connRC.Close();
                }
                catch (Exception ex)//Этот эксепшн на случай отсутствия соединения с сервером.
                {
                    result.ErrorText = ex.Message;
                    result.HasError = true;
                }
            
                return result;

            }

        }
    }
}


Пример использования:
MySqlLib.MySqlData.MySqlExecuteData.MyResultData result = new MySqlLib.MySqlData.MySqlExecuteData.MyResultData();

result = MySqlLib.MySqlData.MySqlExecuteData.SqlReturnDataset("select * from table_name", "Database=base;Data Source=localhost;User Id=root;Password=pass");

            if (result.HasError == false)
            {
                dataGridView1.Columns.Clear();
                dataGridView1.DataSource = result.ResultData.DefaultView;
            }
            else
            {
                MessageBox.Show(result.ErrorText);
            }

В данном примере происходит заполнение DataGridView данными из таблицы базы данных, при этом для всего действия, по сути необходима пара строчек кода.

Скачать исходные коды примеров: MySQLLibExample.rar

17 комментариев

avatar
Долго искал но не смог найти решение.
Подскажите пожалуйста, как можно используя этот класс вывести данные в несколько textbox(ов).
к примеру есть запрос,
SELECT fio,adress,info FROM users WHERE id='10'

соответственно для каждого поля свой textbox (textbox_fio, textbox_adress, textbox_info)
avatar
Вот так, например:
//Проверяем есть ли в выборке вообще хоть что-то?
if (result.ResultData.DefaultView.Table.Rows.Count > 0)
{
  //Помещаем значения в текстовые поля.
  textbox_fio.Text = result.ResultData.DefaultView.Table.Rows[0]["fio"].ToString();
  textbox_adress.Text = result.ResultData.DefaultView.Table.Rows[0]["adress"].ToString();
  textbox_info.Text = result.ResultData.DefaultView.Table.Rows[0]["info"].ToString();
}
avatar
ГРОМАДНОЕ СПАСИБО!
Третий день решение искал.
avatar
Здравствуйте! не подскажите, где можно скачать пример написанной программы на C# ну или хотя листинг кода, с использованием этого класса, в котором реализовано хотя бы добавление, редактирование и удаление данных, в сети я ничего не нашел! заранее спасибо!
avatar
надежда только на вас!
avatar
Вообще класс был написан изначально в качестве примера написания класса. Сам по себе подобного рода класс я создаю как прослойку с которой в итоге программа работает, правда добавляю в него постраничную выборку результатов и другие удобности, чтобы не реализовывать их по 10 раз в коде.

В примере показана только выборка, вообще можно делать и вставку, изменение, и удаление позиций, для этого есть метод:
MySqlLib.MySqlData.MySqlExecute.SqlNoneQuery

Вот, пример того как заставить его работать:
MySqlLib.MySqlData.MySqlExecute.MyResult result = new MySqlLib.MySqlData.MySqlExecute.MyResult();

            result = MySqlLib.MySqlData.MySqlExecute.SqlNoneQuery("insert into table (field1, field2) values ('value1','value2')", "Database=inventar_alleya;Data Source=localhost;User Id=root;Password=240580");
            
            if (result.HasError == false)
            {
                MessageBox.Show("Запрос успешно выполнен!");
            }
            else
            {
                MessageBox.Show(result.ErrorText);
            }


Ещё есть метод при помощи которого можно запускать запросы возвращающие один параметр (значение). Например выборку количества записей или максимального значения поля.
MySqlLib.MySqlData.MySqlExecute.SqlScalar

Вот пример:
MySqlLib.MySqlData.MySqlExecute.MyResult result = new MySqlLib.MySqlData.MySqlExecute.MyResult();

            result = MySqlLib.MySqlData.MySqlExecute.SqlScalar("select count(*) from table1", "Database=inventar_alleya;Data Source=localhost;User Id=root;Password=240580");

            if (result.HasError == false)
            {
                MessageBox.Show("Количество строк в таблице: "+result.ResultText);
            }
            else
            {
                MessageBox.Show(result.ErrorText);
            }
avatar
ок! спасибо большое!
avatar
Здравствуйте!
Нашел поиском эту библиотеку, она замечательная, но у меня есть по ней вопрос, ибо самому додуматься никак не получается…
Вот у меня есть запрос:
result = MySqlLib.MySqlData.MySqlExecuteData.SqlReturnDataset("Select catname from category", "Database=mysqlcp;Data Source=localhost;User Id=root;Password=");


Собственно как мне полученную через этот запрос информацию вывести в ComboBox?(в наличии имеется ComboBox с название bcat, но, думаю, это не играет роли:))
С уважением,
Hudson.
avatar
Элементарно:
comboBox.DataSource = result.ResultData.DefaultView;
comboBox.ValueMember = "ID"; //Поле со значениями
comboBox.DisplayMember = "NAME"; //Поле которое содержит отображаемые данные

//Чтобы получить выбранное значение делаем так
переменная = comboBox1.SelectedValue;
avatar
Большое спасибо:) Все таки ход моих мыслей был верным, вот тольк до
comboBox.ValueMember = "ID"; //Поле со значениями

я не додумался...:)
avatar
В чём смысл comboBox.ValueMember и comboBox.DisplayMember,
если в выборке из MySQL содержится всего одна колонка со значениями?

P.S. у меня даже с одним (любым) из них, comboBox правильно заполняется.
avatar
А как можно загрузить в базу файл? Например изображение?
avatar
Лучше всего хранить ссылку на файл, а не сам файл.
avatar
Roman подскажите пожалуйста, как сделать запрос с переменной неопределенного типа.

Пытаюсь сделать запрос такого рода

string SQL = "START TRANSACTION; ";
SQL = SQL + "INSERT INTO tovar (name) VALUES ('test'); ";
SQL = SQL + " SELECT @idtovar:=(last_insert_id()) from tovar; ";
SQL = SQL + " INSERT INTO postup (idTovar) VALUE (@idtovar); ";
SQL = SQL + "COMMIT";
MySqlLib.MySqlData.MySqlExecute.MyResult result = new MySqlLib.MySqlData.MySqlExecute.MyResult();
result = MySqlLib.MySqlData.MySqlExecute.SqlNoneQuery(SQL, database_str);


В phpMyAdmin все прекрасно работает

в c# выдает ошибку: Fatal error encountered during command execution.
avatar
может быть точки_с_запятыми?
avatar
Подскажиет, у меня строка соединения имеет такой вид:
"Data source=10.10.10.10;UserId=user;Password=Pass;database=base;Protocol=Ssl;Character Set=utf8;SSL Key='C:\\ssl.pem';"


Как модернизировать класс??? Что-то сам не разобрался
avatar
Как то так:
connection = "Data source=10.10.10.10;UserId=user;Password=Pass;database=base;Protocol=Ssl;Character Set=utf8;SSL Key='C:\\ssl.pem';"
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.