Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/32: Рейтинг темы: голосов - 32, средняя оценка - 4.72
28 / 20 / 10
Регистрация: 01.12.2018
Сообщений: 186

Небольшая проблема с SQLite

29.11.2021, 18:22. Показов 6730. Ответов 67
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Начну сначала. Есть приложение на Windows Form, которое работает напрямую с этой БД. В самом начале класса главной формы объявлена переменная типа SQLiteConnection, но объект не создан(!). Далее, при загрузке формы создается уже объект и проверяется, есть ли файл базы данных, если нет, создаем его и с помощью CREATE TABLE создаем нужные, а точнее одну таблицу. По всему коду работа с БД выстроена по типу "создал объект-открыл подключение-сделал дела-закрыл подключение", то есть как-то глобально я не открываю подключение. В общем встал вопрос об архивации и восстановлении данных(в учебном процессе, пишу выпускную работу по курсам программиста, не путать с ВУЗом и высшим образованием). С архивацией я разобрался более менее, я просто временно копирую все нужные мне каталоги и файлы, архивирую их и после удаляю те самые временные файлы. Вот с восстановлением из архива все сложнее и в этом и заключается мой вопрос, что при попытке заменить исходный файл БД, ловиться исключение, что файл БД уже используется процессом. Так вот, как мне, хотя бы временно прикрыть использование файла, дабы его заменить из восстанавливаемого архива. Или может я вообще неправильно делаю. Код пока что приводить не будут, так как весь его читать долго будет, да и сделано там по "ребячески", ибо еще учусь. В процессе обсудить какие-либо куски кода не проблема, если появятся дополнительные вопросы. Спасибо!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.11.2021, 18:22
Ответы с готовыми решениями:

Есть небольшая проблема. После добавления слов в коллекцию не переводит. Как исправить ошибку?
using System; using System.Collections.Generic; namespace ConsoleApp3 { class Program { static void...

Небольшая проблема
Я делала задачу №692 на сайте ******** "Бинарные числа" Говорят, что плохой программист – это тот, кто считает, что в одном...

Небольшая Проблема с осями
Добрый вечер. Делаю управление для Rigidbody по туториалу: Каким образом здесь задаются оси, как и тд.?(А то не совсем понимаю) ...

67
785 / 616 / 273
Регистрация: 04.08.2015
Сообщений: 1,713
29.11.2021, 19:26
fakemade, ошибка может возникать в случаях:
1. Если база данных сейчас используется. То есть нужно сначала закрыть Connection к базе данных (полностью отключится от нее), а потом удалить сам файл.
2. Если база данных размещается там, куда пользователь (от имени которого запущена прога) не имеет доступа. Решение: или разместить прогу туда, куда есть доступ у простого пользователя, или же запускай саму апликуху(и вижуалку) от имени администратора.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
29.11.2021, 19:30
У меня простой вопрос: зачем Вы все это делаете: создаете БД, прячете ее в архив, потом удаляете, постом поднимаете из архива и т.д. ? Все это - прерогатива админа БД и для этого есть специальные "штатные" приложения. Вы хотите написать собственный Клиент DB ?
0
28 / 20 / 10
Регистрация: 01.12.2018
Сообщений: 186
30.11.2021, 06:17  [ТС]
Igr_ok,
1) Для этого я специально указал, что везде, где обращаюсь к БД я сначала открываю соединение, после закрываю. Я прочел весь код и везде, где я работаю с бд соединений закрывается, нигде не остается открытым.
2)Я попробую это сделать, если сработает, будет хорошо.
MsGuns, данная процедура нужна для архивации данных и их последующего переноса, то есть не постоянно, а по запросу пользователя. Все делается в рамках учебной работы и "штатные" приложения меня не интересуют, да и специфику такого приложения не представляю, максимум WinRar, которым я могу сделать это. И почему это прерогатива админа БД, если я использую простейшую локальную SQLite3, а архивировать мне нужно не только db, но и файлы, которые лежат рядом с ним. Это приложения каталогизатора книг, который делает локальную библиотеку из имеющихся на ПК книг(с помощью пользователя конечно же), все данные обо всех экземплярах хранятся в БД (в то числе и путь до файла), а сами экземпляры лежат рядом в папках, чтобы я прямо из программы мог запускать нужный мне файл.
0
Эксперт .NET
 Аватар для Usaga
14127 / 9347 / 1350
Регистрация: 21.01.2016
Сообщений: 35,125
30.11.2021, 06:26
Цитата Сообщение от fakemade Посмотреть сообщение
где обращаюсь к БД я сначала открываю соединение, после закрываю. Я прочел весь код и везде, где я работаю с бд соединений закрывается, нигде не остается открытым.
Я правильно понимаю, что у вас по всему коду разбросаны SQLConnection'ы?)
0
28 / 20 / 10
Регистрация: 01.12.2018
Сообщений: 186
30.11.2021, 06:57  [ТС]
Usaga, ну если вы имеете ввиду конструкторы, то да, где надо создаю объект и строку подключения, подключаюсь, делаю дела, отключаюсь. Повторюсь, делается все в рамках учебного проекта, и сейчас необходимо довести до состояния "работает", а не до состояния "красиво, оптимально, приложение ААА класса, которое умеет все на свете и весит 1 килобайт", если вы понимаете о чем я и извините за шутку, если чем то обидел. Пока что нужно решить проблему с архивированием данных программы, а использование другим процессом не позволяет мне архивировать файл самой БД(это я решил путем копирования файлов и их последующего архивирования), а вот обратный процесс не получается(мне нужно по сути удалить папку ресурсов программы, чтобы ее же восстановить из копии). Спасибо!
0
Эксперт .NET
 Аватар для Usaga
14127 / 9347 / 1350
Регистрация: 21.01.2016
Сообщений: 35,125
30.11.2021, 07:05
Цитата Сообщение от fakemade Посмотреть сообщение
ну если вы имеете ввиду конструкторы, то да, где надо создаю объект и строку подключения, подключаюсь, делаю дела, отключаюсь.
Так не делается. Препод вам тоже самое скажет. Но сами смотрите. Если у вас цель научиться писать так, чтобы вас потом никто не взял на работу, право ваше.

Цитата Сообщение от fakemade Посмотреть сообщение
Пока что нужно решить проблему с архивированием данных программы, а использование другим процессом не позволяет мне архивировать файл самой БД(это я решил путем копирования файлов и их последующего архивирования), а вот обратный процесс не получается(мне нужно по сути удалить папку ресурсов программы, чтобы ее же восстановить из копии). Спасибо!
Нужно закрыть все подключения к файлу базы и переписать её файл файлом из архива (или откуда вам там надо).
0
28 / 20 / 10
Регистрация: 01.12.2018
Сообщений: 186
30.11.2021, 07:19  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Так не делается. Препод вам тоже самое скажет. Но сами смотрите. Если у вас цель научиться писать так, чтобы вас потом никто не взял на работу, право ваше.
Ну смотрите, объявить переменную и создать объект в начале никто не мешает, не проблема код причесать попозже.
Цитата Сообщение от Usaga Посмотреть сообщение
Нужно закрыть все подключения к файлу базы и переписать её файл файлом из архива (или откуда вам там надо).
В этом то и суть, что перечитав весь код, везде, где я бы не обращался к файлу БД, я после всех действий закрываю подключение методом Close(). Может есть метод, который позволит все текущие подключения закрыть разом перед действием замены файла? Или переписать код с одним конструктором в начале и использование его по всему классу поможет решить проблему?
0
Эксперт .NET
 Аватар для Usaga
14127 / 9347 / 1350
Регистрация: 21.01.2016
Сообщений: 35,125
30.11.2021, 07:28
Цитата Сообщение от fakemade Посмотреть сообщение
Ну смотрите, объявить переменную и создать объект в начале никто не мешает, не проблема код причесать попозже.
Лучше бы сразу вынести это дело в класс DataAccess.

Цитата Сообщение от fakemade Посмотреть сообщение
В этом то и суть, что перечитав весь код, везде, где я бы не обращался к файлу БД, я после всех действий закрываю подключение методом Close().
А сделали бы не через задницу, весь код не пришлось бы перечитывать, чтобы найти места, где подключение не закрывается.

Цитата Сообщение от fakemade Посмотреть сообщение
Может есть метод, который позволит все текущие подключения закрыть разом перед действием замены файла?
Да, блин) Вынести весь код работы с базой в одни или группу классов расширяющих базовый, где подключение открывается и закрывается. Чтобы всё в одном месте было, а не как масло по хлебу размазано по всему коду.

Пример:

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 class DataAccess
{
    private string _connectionString;
 
    public DataAccess()
    {
        _connectionString = // берём из конфига или ещё откуда
    }
 
    public bool HasBook(string title)
    {
        using(var conn = GetConnection())
       {
          // Запрос
       }
    }
 
    public void AddBook(NewBookModel model)
    {
        using(var conn = GetConnection())
       {
          // Запрос c model
       }
    }
 
    private SQLConnection GetConnection()
    {
       var connection = new SqlConnection(_connectionString);
       connection.Open();
       return connection;
    }
}
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
30.11.2021, 13:29
fakemade, Стесняюсь спросить, а зачем восстановление из архива БД выполняется из приложения ? Почему нельзя "штатными" средствами (WinRar) при закрытом приложении ?
Ну и все, что сказано Usaga, - всю работу с БД следует вынести (инкапсулировать) с один класс (Repository), тогда поиск ошибки сильно упростится, да и основной код сократится и будет проще читаться.

А суть ошибки скорее всего в том, что при восстановлении файл БД шарится (т.е. есть открытое соединение с БД).

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

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

Добавлено через 5 минут
И главное, Ваше приложение явно рассчитано на одного пользователя, тогда зачем все эти открытия-закрытия соединения ?
Это все равно, что при поездке в метро выходить из него на каждой станции на улицу и снова заходить, покупая новый билет, - ну ведь глупо же

Добавлено через 3 минуты
Цитата Сообщение от fakemade Посмотреть сообщение
пишу выпускную работу по курсам программиста
Вы эту работу пишете как слушатель курсов или как методичку для других слушателей ? Надеюсь, что не второе

Добавлено через 1 минуту
Цитата Сообщение от fakemade Посмотреть сообщение
которое работает напрямую с этой БД
Как это "напрямую" ? Можно поподробнее ?
0
28 / 20 / 10
Регистрация: 01.12.2018
Сообщений: 186
30.11.2021, 17:49  [ТС]
Цитата Сообщение от MsGuns Посмотреть сообщение
всю работу с БД следует вынести (инкапсулировать) с один класс (Repository), тогда поиск ошибки сильно упростится, да и основной код сократится и будет проще читаться.
Я конечно вас услышал, не стану с профессионалами в данной сфере спорить, но пока что все для меня это тяжеловато, инкапсулировать, после каким-то образом вызывать. Как пример для меня вообще не понятная строчка из сообщения выше по типу -"return connection", нет, я конечно знаю и понимаю, что такое return, но что зао connection, какой тип данных она возвращает, возвращает ли она одно значение или какой-то массив данных, как все это обработать и так далее. И так по всему выше описанному коду проблема пока для меня понять и переварить это. И естественно я не прошу написать все за меня, я просто хочу разобраться, паралельно читаю книжку по шарпу и metanit читаю тоже.
Цитата Сообщение от MsGuns Посмотреть сообщение
А суть ошибки скорее всего в том, что при восстановлении файл БД шарится (т.е. есть открытое соединение с БД).
Прошу прощения конечно, но я уже неоднократно писал, что везде где открываю соединение, тут же его закрываю. Попробую также сделать проверку на соединение, чтобы при открытом закрыть, но не должно быть этого, так как, повторюсь, взеде его закрываю.
Цитата Сообщение от MsGuns Посмотреть сообщение
Вы эту работу пишете как слушатель курсов или как методичку для других слушателей ? Надеюсь, что не второе
Конечно выпускная как слушатель, как я могу писать что-то для других, если сам пока не понимаю?)
Цитата Сообщение от MsGuns Посмотреть сообщение
Как это "напрямую" ? Можно поподробнее ?
Может я неправильно выразился конечно, пока в терминологии не силен, я имел ввиду, что работаю и манипулирую запросами, типа select и так далее, даже при первом запуске программы, когда файла типа .db еще нет, я его создаю и в нем с помощью CREATE TABLE создаю таблицу на ходу.
0
 Аватар для Andrey-MSK
3320 / 2207 / 387
Регистрация: 14.08.2018
Сообщений: 7,431
Записей в блоге: 4
30.11.2021, 18:00
Цитата Сообщение от fakemade Посмотреть сообщение
но пока что все для меня это тяжеловато, инкапсулировать, после каким-то образом вызывать
Примерно так, а вызывать через экземпляр класса в нужном месте. В BaseDA прописана строка подключения и еще много для моих нужд.
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
 
using DALibrary.Interfaces;
 
using DALModels.Models;
 
namespace DALibrary.DataAccess
{
    public sealed class EObjectDA : BaseDA, IDataAccessAsync<EObject>
    {
        public async Task AddItemAsync(EObject itemToAdd)
        {
            string sqlText =
                "INSERT INTO dbo.tblEObject(EObjectName) VALUES(@eoName); " +
                "SELECT @newID = SCOPE_IDENTITY();";
 
            using (SqlConnection sqlConnection = new SqlConnection(_connectionString))
            {
                try
                {
                    await sqlConnection.OpenAsync();
 
                    SqlCommand sqlCommand = new SqlCommand(sqlText, sqlConnection)
                    {
                        CommandType = CommandType.Text
                    };
 
                    SqlParameter parameterEOName = new SqlParameter
                    {
                        ParameterName = "@eoName",
                        Value = itemToAdd.EObjectName,
                        SqlDbType = SqlDbType.NVarChar,
                        Size = 200,
                        Direction = ParameterDirection.Input
                    };
                    sqlCommand.Parameters.Add(parameterEOName);
 
                    SqlParameter parameterNewID = new SqlParameter
                    {
                        ParameterName = "@newID",
                        SqlDbType = SqlDbType.Int,
                        Direction = ParameterDirection.Output
                    };
                    sqlCommand.Parameters.Add(parameterNewID);
 
                    await sqlCommand.ExecuteNonQueryAsync();
 
                    itemToAdd.EObjectID = (int)sqlCommand.Parameters["@newID"].Value;
                }
                catch (Exception ex)
                {
                    throw new ApplicationException("Ошибка записи нового объекта строительства.", ex);
                }
            }
        }
 
        public async Task<List<EObject>> GetAllAsync()
        {
            List<EObject> eObjects = new List<EObject>();
            string sqlText =
                "SELECT ID_EObject, EObjectName FROM dbo.tblEObject ORDER BY EObjectName";
 
            using (SqlConnection sqlConnection = new SqlConnection(_connectionString))
            {
                try
                {
                    await sqlConnection.OpenAsync();
 
                    SqlCommand sqlCommand = new SqlCommand(sqlText, sqlConnection)
                    {
                        CommandType = CommandType.Text
                    };
 
                    using (SqlDataReader sqlDataReader = await sqlCommand.ExecuteReaderAsync())
                    {
                        while (await sqlDataReader.ReadAsync())
                        {
                            eObjects.Add(new EObject
                            {
                                EObjectID = (int)sqlDataReader["ID_EObject"],
                                EObjectName = sqlDataReader["EObjectName"] as string ?? ""
                            });
                        }
                    }
 
                    return eObjects;
                }
                catch (Exception ex)
                {
                    throw new ApplicationException("Ошибка загрузки данных по объектам строительства.", ex);
                }
            }
        }
 
        public async Task<EObject> GetByIDAsync(int itemID)
        {
            EObject eObject = new EObject();
            string sqlText =
                "SELECT ID_EObject, EObjectName FROM dbo.tblEObject WHERE ID_EObject = @id";
 
            using (SqlConnection sqlConnection = new SqlConnection(_connectionString))
            {
                try
                {
                    await sqlConnection.OpenAsync();
 
                    SqlCommand sqlCommand = new SqlCommand(sqlText, sqlConnection)
                    {
                        CommandType = CommandType.Text
                    };
 
                    SqlParameter parameterID = new SqlParameter
                    {
                        ParameterName = "@id",
                        Value = itemID,
                        SqlDbType = SqlDbType.Int,
                        Direction = ParameterDirection.Input
                    };
                    sqlCommand.Parameters.Add(parameterID);
 
                    using (SqlDataReader sqlDataReader = await sqlCommand.ExecuteReaderAsync())
                    {
                        while (await sqlDataReader.ReadAsync())
                        {
                            eObject.EObjectID = (int)sqlDataReader["ID_EObject"];
                            eObject.EObjectName = sqlDataReader["EObjectName"] as string ?? "";
                        }
                    }
 
                    return eObject;
                }
                catch (Exception ex)
                {
                    throw new ApplicationException("Ошибка загрузки данных по объектам строительства.", ex);
                }
            }
        }
 
        public async Task RemoveItemAsync(EObject itemToRemove)
        {
            string sqlText =
                "DELETE dbo.tblEObject WHERE ID_EObject = @eoID";
 
            using (SqlConnection sqlConnection = new SqlConnection(_connectionString))
            {
                try
                {
                    await sqlConnection.OpenAsync();
 
                    SqlCommand sqlCommand = new SqlCommand(sqlText, sqlConnection)
                    {
                        CommandType = CommandType.Text
                    };
 
                    SqlParameter parameterID = new SqlParameter
                    {
                        ParameterName = "@eoID",
                        Value = itemToRemove.EObjectID,
                        SqlDbType = SqlDbType.Int,
                        Direction = ParameterDirection.Input
                    };
                    sqlCommand.Parameters.Add(parameterID);
 
                    await sqlCommand.ExecuteNonQueryAsync();
                }
                catch (Exception ex)
                {
                    throw new ApplicationException("Ошибка удаления объекта строительства.", ex);
                }
            }
        }
 
        public async Task UpdateItemAsync(EObject itemToUpdate)
        {
            string sqlText = 
                "UPDATE dbo.tblEObject SET EObjectName = @eoName " +
                "WHERE ID_EObject = @eoID";
 
            using(SqlConnection sqlConnection=new SqlConnection(_connectionString))
            {
                try
                {
                    await sqlConnection.OpenAsync();
 
                    SqlCommand sqlCommand = new SqlCommand(sqlText, sqlConnection)
                    {
                        CommandType = CommandType.Text
                    };
 
                    SqlParameter parameterEOName = new SqlParameter
                    {
                        ParameterName = "@eoName",
                        Value = itemToUpdate.EObjectName,
                        SqlDbType = SqlDbType.NVarChar,
                        Size = 200,
                        Direction = ParameterDirection.Input
                    };
                    sqlCommand.Parameters.Add(parameterEOName);
 
                    SqlParameter parameterID = new SqlParameter
                    {
                        ParameterName = "@eoID",
                        Value = itemToUpdate.EObjectID,
                        SqlDbType = SqlDbType.Int,
                        Direction = ParameterDirection.Input
                    };
                    sqlCommand.Parameters.Add(parameterID);
 
                    foreach (SqlParameter parameter in sqlCommand.Parameters)
                    {
                        if (parameter.Value == null)
                        {
                            parameter.Value = DBNull.Value;
                        }
                    }
 
                    await sqlCommand.ExecuteNonQueryAsync();
                }
                catch (Exception ex)
                {
                    throw new ApplicationException("Ошибка обновления объекта строительства.", ex);
                }
            }
        }
    }
}
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
30.11.2021, 19:07
Цитата Сообщение от fakemade Посмотреть сообщение
Прошу прощения конечно, но я уже неоднократно писал, что везде где открываю соединение, тут же его закрываю. Попробую также сделать проверку на соединение, чтобы при открытом закрыть, но не должно быть этого, так как, повторюсь, взеде его закрываю.
Пользуетесь ли Вы Клиентом для работы "непосредственно" с базой данных ? Каким-нибудь SqlliteStudio ?
Если да и в момент запуска Вашего приложения Клиент активен и там открыта Ваша база, то эффект будет тот же - восстановления базы из архива не произойдет, т.к. она (база) юзается (шарится) этим Клиентом.
Закройте Клиент или разорвите соединение с базой в нем и повторите попытку разархивации базы из приложения.

Но, повторюсь еще раз, это - плохая манера.

Andrey-MSK, Ну и примерчик Вы ему выложили Дай Бог ему разобраться хотя бы с основами, а тут...
0
28 / 20 / 10
Регистрация: 01.12.2018
Сообщений: 186
30.11.2021, 19:22  [ТС]
Цитата Сообщение от MsGuns Посмотреть сообщение
Пользуетесь ли Вы Клиентом для работы "непосредственно" с базой данных ? Каким-нибудь SqlliteStudio ?
Если да и в момент запуска Вашего приложения Клиент активен и там открыта Ваша база, то эффект будет тот же - восстановления базы из архива не произойдет, т.к. она (база) юзается (шарится) этим Клиентом.
Закройте Клиент или разорвите соединение с базой в нем и повторите попытку разархивации базы из приложения.
Ну я уж не совсем глупый, высшее техническое образование как никак есть и с ПК я работаю хорошо. Да и плюс к тому, С изучал ранее на неплохом уровне и такие очевидные вещи я сразу исключил естественно. Проблема решилась путем введения следующего куска
C#
1
2
3
4
if(DB.State == ConnectionState.Closed)
{
//Здесь все действия
}
После этого спокойно в процессе работы приложения основная папка с ресурсами удаляется (в ней же лежит и файл бд) и копируется новая из целевого архива. Не знаю, каким образом все это работает, но работает в моем случае только так.
Еще вопрос, может оффтоп, но не могли бы вы посоветовать книгу по С#. По С читал Дейтлов, там очень удобная подача материала + задачи в конце каждой главы и хотелось бы аналогичную по С#, чтобы с задачками. Только благодаря совместному труду и чтению Дейтелов я смог понять С и сложные там темы, по типу указателей и т.д., хотелось бы также и с С# разобраться. Спасибо.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
30.11.2021, 20:32
fakemade, Хейлсберг однозначно. Но материал нужно кушать с практикой (VS подходит идеально), тогда заходит отлично.

Добавлено через 1 минуту
Мне лично очень здорово помог опыт Delphi, по крайней мере азы ООП я уже знал твердо
0
 Аватар для Andrey-MSK
3320 / 2207 / 387
Регистрация: 14.08.2018
Сообщений: 7,431
Записей в блоге: 4
01.12.2021, 09:01
MsGuns, Дык это, там всё как в книжке, ниче сложного нет
Ну если только async/await и Task убрать то будет прям как в учебнике

Добавлено через 10 минут
fakemade, Чтоб было понятнее что откуда берётся, покажу BaseDA и IDataAccessAsync.
И всю работу с БД нужно производить асинхронными методами, чтоб приложение не замирало на время обработки запроса и получения данных.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System.Collections.Generic;
using System.Threading.Tasks;
 
namespace DALibrary.Interfaces
{
    /// <summary>
    /// <br>Базовый интерфейс для выполнения стандартных операций с БД.</br>
    /// <br>Реализует асинхронные методы доступа.</br>
    /// </summary>
    /// <typeparam name="T">Класс объекта таблицы.</typeparam>
    internal interface IDataAccessAsync<T>
    {
        Task<List<T>> GetAllAsync();
        Task<T> GetByIDAsync(int itemID);
        Task AddItemAsync(T itemToAdd);
        Task UpdateItemAsync(T itemToUpdate);
        Task RemoveItemAsync(T itemToRemove);
    }
}
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
using System.Configuration;
using System.IO;
 
namespace DALibrary.DataAccess
{
    public class BaseDA
    {
        protected readonly string _connectionString = ConfigurationManager.ConnectionStrings["SQLConnect"].ConnectionString;
 
        protected BaseDA() { }
 
        protected string GetExcelConnectionString(string pathToFile)
        {
            string extension = Path.GetExtension(pathToFile);
            string excelConString = string.Empty;
 
            switch (extension)
            {
                case ".xls":
                    excelConString = ConfigurationManager.ConnectionStrings["ExcelXLSConnect"].ConnectionString;
                    break;
                case ".xlsx":
                    excelConString = ConfigurationManager.ConnectionStrings["ExcelXLSXConnect"].ConnectionString;
                    break;
            }
 
            return string.Format(excelConString, pathToFile);
        }
    }
}
И еще нужно все классы по работе с БД положить в отдельный проект, и дать доступ внешним сборкам не к самим классам, а только к одной точке входа в эту библиотеку, тогда гарантированно у вас будет один объект с доступом к данным.
Как-то примерно так:
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
using MEFCFDAL.Interfaces;
using MEFCFDAL.Model;
 
namespace MEFCFDAL.DataAccess
{
    public sealed class MainDA : IMainDA
    {
        public EObjectDA EObjectDA { get; }
        public GPlanDA GPlanDA { get; }
        public ReportDA ReportDA { get; }
        public DrawDA DrawDA { get; }
        public DrawSystemDA DrawSystemDA { get; }
        public DrawSpecificationDA DrawSpecificationDA { get; }
        public ExcelDA ExcelDA { get; }
        public RawSqlDA RawSqlDA { get; }
        public LaborDA LaborDA { get; }
 
        public MainDA()
        {
            EObjectDA = new EObjectDA();
            GPlanDA = new GPlanDA();
            ReportDA = new ReportDA();
            DrawDA = new DrawDA();
            DrawSystemDA = new DrawSystemDA(_);
            DrawSpecificationDA = new DrawSpecificationDA();
            ExcelDA = new ExcelDA();
            RawSqlDA = new RawSqlDA();
            LaborDA = new LaborDA();
        }
    }
}
Добавлено через 7 минут
И еще к нему можно прикрутить Dispose, что бы уже точно всё уничтожилось

Добавлено через 22 минуты
И в вызывающей сборке создавать объект доступа вот так, с проверкой на null, чтоб объект был один, либо этот класс можно оформить под паттерн Одиночка
C#
1
2
3
4
if (_mainDA == null)
{
    _mainDA = new MainDA();
}
0
28 / 20 / 10
Регистрация: 01.12.2018
Сообщений: 186
01.12.2021, 10:27  [ТС]
MsGuns, ну хейлберга я полистал в электронном варианте. Нашёл в бумажном, могу заказать, крайняя книга 2012 года, насколько она актуальна под современные реалии языка? Ну и соответственно как таковых задач там нет, тогда вопрос о практике остаётся открытым все равно, где же взять эту практику? И книжка Хейлберга самая популярная и доступная в плане подачи знаний? Или есть ещё лучше?
Andrey-MSK, я конечно послал в закладки, но пока что для меня это ещё ничего не значит пока. Изучу основы, после смогу посмотреть на это с другой стороны) Всё равно спасибо!
0
 Аватар для Andrey-MSK
3320 / 2207 / 387
Регистрация: 14.08.2018
Сообщений: 7,431
Записей в блоге: 4
01.12.2021, 10:31
Цитата Сообщение от fakemade Посмотреть сообщение
Изучу основы
Основы
0
28 / 20 / 10
Регистрация: 01.12.2018
Сообщений: 186
01.12.2021, 10:36  [ТС]
Andrey-MSK, я больше склоняюсь к литературе, тем более бумажной, чтобы было проще, тяжело читать электронные книги, не то, что сайты. Я понимаю, загуглить какой-то конкретный вопрос, это можно, а вот так изучать основы, не хотелось бы, поэтому и спрашиваю про книгу.
0
 Аватар для Andrey-MSK
3320 / 2207 / 387
Регистрация: 14.08.2018
Сообщений: 7,431
Записей в блоге: 4
01.12.2021, 10:47
fakemade, я вот с такой начинал, это последняя версия этой книги
Язык программирования C# 7 и платформы .NET и .NET Core | Джепикс Филипп, Троелсен Эндрю
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.12.2021, 10:47
Помогаю со студенческими работами здесь

Небольшая проблема с классами
Всем привет. Дано задание: Расширить иерархию классов с использованием виртуального абстактного класса в качестве основы иерархии. ...

Небольшая проблема в проектировании БД
Доброго времени суток! Возник вопрос проектировочного характера. Есть 3 таблицы, описывающие взаимосвязь между сущностями...

Небольшая проблема с кодом
Доброго времени суток. Столкнулся с такой вот проблемой: смотрел я как-то вэбинар на тему написания игры &quot;Сапер&quot; на джаве. Само...

Cportlib небольшая проблема
Доброго времени суток. Пытаюсь работать с компонентом, для передачи и получения байтов в порт по протоколу modbus. Тут все просто....

Небольшая проблема с модулем
Компилятор обнаружил ошибку в конце кода (скриншот) Unit cmplx; Interface const kol1 = 9; kol2 = 14; type с =...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK сделайте это, JDK, то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера . . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru