C# библиотека доступа к базе данных SQLite. Часть 1

И немного рекламы:

Предисловие

Итак, после долгих мучений с различными базами данных, было решено написать что-то такое, что могло упростить разработку приложения, работающего с какой-либо базой данных. Я заметил, что в каждом моем проекте приходится писать одно и тоже, когда это касается получения, вставки и т.д. в базу. Разбирая ZEND FRAMEWORK наткнулся на готовый класс, который значительно упрощал доступ к данным, хранящихся в базе. Решение, конечно, не для кул-хацкеров, но для написания повседневных программ «для себя» и «для других» подходит. Это первая часть в цикле статей, в которых, шаг за шагом будем создавать класс, призванный помочь в решении поставленной задачи.

Инструментарий

Для первой части я создал простой проект. Скажу сразу: в роли подопытной базы данных будем использовать SQLITE. Ей не нужен сервер, а для теста нашего класса ее хватит. Если вам понадобиться использовать класс для работы с MSSQL или MYSQL, то можно будет очень просто и быстро произвести нужные замены в классе.
Библиотеку SQLITE я приложил к проекту. Она 32-битная. 64-битную версию ищите здесь.

Реализация

Ядро нашего проекта — это файл dbFacade.cs. В нем будет описываться вся работа с базой данных. Этот файлы вы можете копировать в другой проект и пользоваться им как родным.
Давайте теперь рассмотрим структуру файла. Первая версия будет только создавать новый файл со структурой базы и читать его.

Основные настройки. Задаем сразу, чтобы потому не морочить себе голову.

//путь к файлу базы
public static string filename = Path.Combine(Application.StartupPath, "working.db");
//строка подключения
string ConnectionString = string.Format("data source={0};New=True;UseUTF16Encoding=True", filename);
[/sharp]

Первая важная функция создает файл со структурой. 
[csharp]
public void CreateDatabase()
{
    //SQL-запрос для таблицы
    string sql_test = @"CREATE TABLE 'Test'(
'id' INTEGER PRIMARY KEY AUTOINCREMENT,
'title' TEXT,
'status' tinyint,
'topic_id' INTEGER,
'testdate' datetime NOT null DEFAULT '2009-10-07')";

    //SQL-запрос для индексации поля testdate
    string sql_createindex = "CREATE UNIQUE INDEX testdate_indx ON Test (testdate)";

    ConnectionState previousConnectionState = ConnectionState.Closed;
    using (SQLiteConnection connect = new SQLiteConnection(ConnectionString))
    {
        try
        {
            //проверяем предыдущее состояние
            previousConnectionState = connect.State;
            if (connect.State == ConnectionState.Closed)
            {   
                //открываем соединение
                connect.Open();
            }
            //создаем новую таблицу
            SQLiteCommand command = new SQLiteCommand(sql_test, connect);
            command.ExecuteNonQuery();

            //создаем индексацию
            command.CommandText = sql_createindex;
            command.ExecuteNonQuery();
        }
        catch { }
        finally
        {
            //закрываем соединение, если оно было закрыто перед открытием
            if (previousConnectionState == ConnectionState.Closed)
            {
                connect.Close();
            }
        }
    }
}

Смотрите, SQLiteConnection, если его просто переименовать в SQLConnection, то это будет уже работа с MSSQL. Также и SQLiteCommand меняется на SQLCommand. И ВСЕ! После этих смен, эта функция уже будет работать с MSSQL. Вот так все просто… пока просто :)
Далее… вторая функция. Простая функция. Достает все данные из всех столбцов. Можно с условиями и различными параметрами. Т.е. простой запрос, без всяких там связываний с другими таблицами и т.д.

public DataTable FetchAll(string databasename, string where, string etc)
{
    DataTable dt = new DataTable();
	//создаем строку запроса
    string sql = string.Format("SELECT * FROM {0} {1} {2}", databasename, where, etc);
    ConnectionState previousConnectionState = ConnectionState.Closed;
    using (SQLiteConnection connect = new SQLiteConnection(ConnectionString))
    {
        try
        {
            previousConnectionState = connect.State;
            if (connect.State == ConnectionState.Closed)
            {
                connect.Open();
            }
            SQLiteCommand command = new SQLiteCommand(sql, connect);
            SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
			//заполняем таблицу
            adapter.Fill(dt);
        }
        catch (Exception error) { 
            System.Windows.Forms.MessageBox.Show(error.Message, "Ошибка при получении данных из базы", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return null; }
        finally
        {
            if (previousConnectionState == ConnectionState.Closed)
            {
                connect.Close();
            }
        }
    }
	//возвращаем таблицу
    return dt;
}

Это была простая функция, для простого запроса. То, что она большая, так это просто куча проверок различных.
И еще одна функция для получения данных из избранных колонок:

public DataTable FetchByColumn(string databasename, string[] columns, string where, string etc)
{
     DataTable dt = new DataTable();
    string textofcolumns = string.Empty;

    if (columns == null || columns.Length == 0)
        textofcolumns = "*";
    else
    {
        bool ifFirst = true;
        //собираем все названия колонок в строку
        foreach (string col in columns)
        {
            if (ifFirst)
            {
                textofcolumns = col;
                ifFirst = false;
            }
            else
                textofcolumns += "," + col;
        }
    }

    string sql = string.Format("SELECT {0} FROM {1} {2} {3}", textofcolumns, databasename, where, etc);
    ConnectionState previousConnectionState = ConnectionState.Closed;
    using (SQLiteConnection connect = new SQLiteConnection(ConnectionString))
    {
        try
        {
            previousConnectionState = connect.State;
            if (connect.State == ConnectionState.Closed)
            {
                connect.Open();
            }
            SQLiteCommand command = new SQLiteCommand(sql, connect);
            SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
            adapter.Fill(dt);
        }
        catch (Exception error)
        {
            System.Windows.Forms.MessageBox.Show(error.Message, "Ошибка при получении данных из базы", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return null;
        }
        finally
        {
            if (previousConnectionState == ConnectionState.Closed)
            {
                connect.Close();
            }
        }
    }
    return dt;
}

В эту функция мы передаем массив из колонок. Разбираем его, создаем запрос, выполняем. Отличается от предыдущей функции только передачей массива колонок.
Дополнительно описаны функции без передачи некоторых параметров. Типа:

public DataTable FetchAll(string databasename)
{
    return FetchAll(databasename, "", "");
}

и

public DataTable FetchAll(string databasename, string where)
{
    return FetchAll(databasename, where, "");
}

Заключение

Вот и разобрали первую версию чудо-библиотеки.
К проекту приложена простенькая заполненная база данных working.db. Просто для наглядности.

Файлы проекта целиком>>>
Файл dbFacade.cs последней версии.

туризм

Теги: ,

Если у вас возникли вопросы, вы можете оставить их в комментариях

Комментарии к статье

23 Ответов на “C# библиотека доступа к базе данных SQLite. Часть 1”

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

(обязательно)

(обязательно)