Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# Windows Forms
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
defond57
1 / 1 / 0
Регистрация: 08.03.2013
Сообщений: 18
1

Создание единого подключения для всего проекта

20.07.2018, 09:47. Просмотров 713. Ответов 3
Метки sql (Все метки)

Здравствуйте.

Нужна небольшая помощь. Имеется БД (SQLite). Раньше я перед каждым действием с БД создавал соединение, получал нужные данные и закрывал соединение.

Пример
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public static void ExecuteSqlTransaction(string Zapros)
        {
            string dbFileName = @"res\db\def.db";
            
            using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + dbFileName + ";mode=Exclusive;datetimeformat=CurrentCulture"))
            {
                connection.Open();
 
                //string Zapros = "insert into Def_LMSZ (guid, id_anketa, guid_msz) " +
                //    "values ('" + new_guid + "','" + Perem.id_anketa + "','" + guid_LMSZ + "')";
                // где new_guid - новый гуид
                //     Perem.id_anketa - номер
                //     guid_LMSZ - гуид из другой таблицы
 
                using (SQLiteTransaction dbTrans = connection.BeginTransaction())
                {
                    using (SQLiteCommand cmd = connection.CreateCommand())
                    {
                        cmd.CommandText = Zapros;
                        cmd.ExecuteNonQuery();
                    }
                    try
                    {
                        dbTrans.Commit();
                    }
                    catch
                    {
                        MessageBox.Show("Жопа какая то!");
                    }
                }
            }
        }
Всегда такой вариант устраивал. Сейчас столкнулся с тем, что запрос из примера блокирует БД. Причем рандомно - может пару раз выполниться, затем БД всегда будет заблокирована при INSERT, но доступна в Shell или для SELECT.

Мне посоветовали сделать одно единое соединение с БД для всего проекта. Хотя вот тут этого крайне не рекомендуют. Да и в MSDN все примеры завязаны на using.

Суть вопроса - нужно ли делать одно соединение хотя бы в рамках одной формы? И как это лучше сделать, если у меня в одной форме вначале выполняется SELECT для наполнение DataGrid, а по данным выбранного элемента, делается INSERT.

тоже задавал вопрос. Как видите результата пока нет.

Я уже просто не знаю, что делать. Советы всех знакомых тоже не помогли.

Добавлено через 4 минуты
Цитата Сообщение от defond57 Посмотреть сообщение
но доступна в Shell
Имел в виду, что в Shell тот же самый Insert выполняется сколько угодно раз подряд, без превышения времени блокировки на запись. Т.е. несколько мс.

И да, я пытался пересоздавать БД, класс обработки, вообще весь проект перезаписывал. Менял драйвера.
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.07.2018, 09:47
Ответы с готовыми решениями:

MEF создание единого репозитория для запроса
В продолжение єтой темы......

Переменные для всего проекта
Делаю приложение на основе БД! Несколько форм этого приложения работают с...

Обработчик ошибок для всего проекта
Как создать обработчик ошибок для всего проекта? Ну, то есть, можно создать...

создание dll для подключения к бд oracle
Пытаюсь вынести подключение к бд oracle в dll. Подскажите, пожалуйста, как...

Инсталлятор для создания единого ехе с выбранными пользователем файлами?
решил написать инсталлятор я открытым кодом чтобы был бесплатным.Отсюда...

3
Someone007
2434 / 1910 / 871
Регистрация: 09.05.2015
Сообщений: 4,722
Завершенные тесты: 1
20.07.2018, 09:54 2
Лучший ответ Сообщение было отмечено defond57 как решение

Решение

Что мешает сделать что нибудь типа этого, и потом вызывать откуда угодно?

C#
1
Database.ExecuteSqlTransaction("xxx");
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    class Database
    {
        const string dbFileName = @"res\db\def.db";
        private static SQLiteConnection connection;
 
        static Database()
        {
            connection = new SQLiteConnection("Data Source=" + dbFileName + ";mode=Exclusive;datetimeformat=CurrentCulture");
            connection.Open();
        }
 
        public static Close()
        {
            connection.Close();
        }
 
        // можно также добавить методы для получения данных при необходимости...
 
        public static void ExecuteSqlTransaction(string query)
        {
            using (SQLiteTransaction dbTrans = connection.BeginTransaction())
            {
                using (SQLiteCommand cmd = connection.CreateCommand())
                {
                    cmd.CommandText = query;
                    cmd.ExecuteNonQuery();
                }
                try
                {
                    dbTrans.Commit();
                }
                catch
                {
                    MessageBox.Show("Жопа какая то!");
                }
            }
        }
    }
1
Mantisuma
0 / 0 / 0
Регистрация: 30.11.2016
Сообщений: 6
20.07.2018, 09:55 3
В любом случае нужно контролировать исполнение запроса
Если запрос не прошел или соединение разорвалось то все заново
Обычно такие вещи делаются в отдельном потоке
0
defond57
1 / 1 / 0
Регистрация: 08.03.2013
Сообщений: 18
20.07.2018, 10:39  [ТС] 4
Цитата Сообщение от Someone007 Посмотреть сообщение
Что мешает сделать что нибудь типа этого, и потом вызывать откуда угодно?
Так и делаю. У меня один класс для работы с БД.
Но немного в другом исполнении. Сейчас попробую Ваш вариант и отпишусь.

Добавлено через 6 минут
Цитата Сообщение от Mantisuma Посмотреть сообщение
Если запрос не прошел или соединение разорвалось то все заново
Так я контролирую. Проблема в том, что при выполнении именно этого Инсерта происходит блокировка БД до его выполнения. Ошибок нет. Такое ощущение, что срабатывает глобальная блокировка. А я не могу понять, что именно может вызывать её срабатывание.

Раз в Шелл запрос выполняется без проблем, значит дело в коде. Код вылизан согласно инструкций MSDN. Значит, как я понимаю, дело или в драйвере, или в поведении ПО. Драйвер я сменил. Значит дело в поведении ПО. Возможно дело в превышении количества открытий БД при Инсерте. Возможно БД "предполагает", что у меня многопоточная работа с БД SQLite , что противоречит её концепции. Что и вызывает глобальный блок на запись.

Но это только мое видение. Возможно дело в чем то другом.

Добавлено через 14 минут
Цитата Сообщение от Someone007 Посмотреть сообщение
public static Close()
Ох я и туплю с утра
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.07.2018, 10:39

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

Создание окошка, всегда висящего поверх всего
Создаю менеджер для буфера обмена. Для этого хочу создать черную полоску с...

Создание проекта
Здраствуйте, Месяца 3 назад начал делать программу, для просмотра информации о...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru