С# Пишем DELETE для SQLite. Часть 3

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

Продолжаем писать библиотеку быстрого доступа для новых программ под SQLite. В первых двух частях (здесь и здесь) были описаны операции SELECT и INSERT. Сегодня, на ваш суд, я представляю код для операции DELETE. Операция жесткая… Пользоваться аккуратно. Можно остаться без данных, а может и без пальцев ;) , смотря какие данные завалить.

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

Реализация

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

public int Delete(string tablename)
public int Delete(string tablename, string where)
public int Delete(string tablename, string column, object[] collection)

Первые два метода похожи. Отличие только в том, что второй принимает условие, наряду с названием таблицы. Вот часть кода, которая отвечает за выполнение запроса:

string sql = string.Format("DELETE FROM {0} {1}", tablename, where);
...
SQLiteCommand command = new SQLiteCommand(sql, connect);
command.ExecuteNonQuery();

Здесь, как мы видим все просто. Но существуют такие ситуации, когда записей, которых необходимо удалить, много. И они находятся в разных местах таблицы. Каждый раз посылать запрос на удаление одной записи нелогично, т.к. это занимает много времени. Каждый раз происходит подключение и отключение от базы, а это требует времени. Рассмотрим код, который работает нерационально, используя наш второй метод:

foreach (DataGridViewRow row in grdMain.SelectedRows)
{
    db.Delete("test", "WHERE id = " + row.Cells[0].Value;
}

В цикле мы проходим по всем выделенным строкам и каждую удаляем. Если 2-3 строки, то работает незаметно, но если их хотя бы 100 и больше — появляются задержки.

Решение проблемы лежит в одном запросе, который содержит условия для всех удаляемых строк. В блоке условий WHEREперечисляем все наши условия разделяя их оператором OR. Тогда запрос выглядит следующим образом:

DELETE FROM test WHERE id = 1 OR id = 2 OR id = 100

Думаю, что с этим все понятно. Теперь сам метод, в котором описана методика построения строки запроса:

public int Delete(string tablename, string column, object[] collection)
{
    ConnectionState previousConnectionState = ConnectionState.Closed;
    using (SQLiteConnection connect = new SQLiteConnection(ConnectionString))
    {
        try
        {
            previousConnectionState = connect.State;
            if (connect.State == ConnectionState.Closed)
            {
                connect.Open();
            }
            #region Создаем строку условий
            bool ifFirst = true;
            string where = string.Empty;
            foreach (object item in collection)
            {
                if (ifFirst)
                {
                    where = "WHERE " + column + " = '" + item + "'";
                    ifFirst = false;
                }
                else
                {
                    where += " OR " + column + " = '" + item + "'";
                }
            }
            #endregion

            string sql = string.Format("DELETE FROM {0} {1}", tablename, where);
            SQLiteCommand command = new SQLiteCommand(sql,connect);
            command.ExecuteNonQuery();
        }
        catch (Exception error)
        {
            System.Windows.Forms.MessageBox.Show(error.Message, "Ошибка при удалении данных из таблицы " + tablename, MessageBoxButtons.OK, MessageBoxIcon.Error);
            return 1;
        }
        finally
        {
            if (previousConnectionState == ConnectionState.Closed)
            {
                connect.Close();
            }
        }
        return 0;
    }
}

Этот метод принимает имя таблицы, имя поля, по которому идет проверка условий, и массив самих условий. В цикле foreach проходим по всем объектам и строим строку, разделяя ее оператором OR. Таким образом в сам метод можно передавать любой массив. Примеры вызова этого метода:

dbFacade db = new dbFacade();
db.Delete("test", "id", new string[] {"1","2","100","200"});
db.Delete("test", "id", new int[] {1,2,100,200});
ArrayList list = new ArrayList();
list.Add(1);
list.Add(2);
list.Add(100);
db.Delete("test", "id", list.ToArray());

Исходя из этого мы можем передавать любой массив объектов, каждый элемент которого можно представить в виде строки. Все три метода возвращают целое число. Если операция удаления прошла успешно, возвращается 0. В остальных случаях код ошибки, который вы можете придумать сами.

Заключение

Вот и разобрали операцию DELETE. Если у вас появятся, какие-либо полезные идеи, пишите мне.
Как обычно вы можете скачать тестовый проект
Прямая ссылка на текущую версию dbFacade

Популярность: 13%

Теги: , ,

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

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

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

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