C # + Удаление DbConnection и DbCommand и перехват ошибки
-
21-09-2019 - |
Вопрос
Я пытаюсь понять DbConnection и DbCommand, а также правильный способ утилизации этих объектов после использования.
Ниже приведен фрагмент кода, который у меня есть.Используя "using statement" в DbConnection и DbCommand, будет ли этого достаточно?Я пытаюсь предотвратить возможную утечку памяти.
2 - й вопрос,
Должен ли я утилизировать объект DbCommand?
большое спасибо
DbProviderFactory fac = DbProviderFactories.GetFactory(this.DatabaseProviderName);
using (DbConnection dbConn = fac.CreateConnection())
{
dbConn.ConnectionString = this.ConnectionString;
using (DbCommand comm = fac.CreateCommand())
{
comm.CommandText = "select * from aTable";
comm.Connection = dbConn;
DataTable targetTable = new DataTable();
DbDataAdapter facDA = fac.CreateDataAdapter();
facDA.SelectCommand = comm;
facDA.Fill(targetTable);
//assuming Adapter would open / close connection (right assumption?)
//do something with the datatable
}
}
Решение
используя using
это то же самое, что и try/finally
блок с dispose()
вызванный в finally
.
DbCommand
должен быть завернут в using
оператор, поскольку он реализует IDisposable
.
Обратите внимание , что DbCommand
на самом деле это абстрактный класс, поэтому вам нужно будет либо
- выводите из этого
- код для интерфейса (
IDbCommand
) - используйте один из предопределенных производных классов, таких как
SqlCommand
.
DbConnection
также является абстрактным классом, поэтому вам нужно будет сделать что-то подобное, как я предложил выше для DbCommand
и за это тоже.
Общая рекомендация заключается в том, что если объект реализует IDisposable
, он должен быть завернут в using
утверждение такое , что Dispose()
вызывается для освобождения ресурсов, даже если внутри блока инструкций генерируется исключение.Тогда в вашем примере хорошей практикой было бы обернуть каждое соединение, команду, DataTable
и DbDataAdapter
объекты в using
заявление.
Другие советы
Да, я бы вызвал Dispose для объекта DbCommand.В общем, правилом должно быть то, что если он реализует IDisposable, вы должны вызывать его метод Dispose при необходимости.На мой взгляд, ваш код выглядит хорошо сформированным.Я думаю, что вы на правильном пути.
Редактировать На самом деле, вы могли бы также обернуть свой DbDataAdapter в оператор using, поскольку он тоже реализует IDisposable .
Обертывание объектов в using
блоков, которые вы делаете, должно быть достаточно;это вызовет кодовый вызов Dispose
даже если возникло исключение.
И да, вы должны сделать это для DbCommand
объект, а также DbDataAdapter
и тот DataTable
.Все они (прямо или косвенно) реализуют IDisposable
.