C# IDisposable Использование: Лучшая Практика
Я уже некоторое время оборачиваю объекты OracleConnection и OracleCommand в операторы USING, однако после запуска анализатора кода я обнаруживаю, что OracleParameter также реализует IDisposable. Правильно ли следующий код? Есть ли лучший метод для читаемости или структуры? На первый взгляд это просто кажется загроможденным с помощью утверждений:
using (OracleConnection conn = new OracleConnection(connectionstring))
{
conn.Open();
using (OracleCommand cmd = new OracleCommand(sql, conn))
{
cmd.BindByName = true;
using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input))
{
param1.Value = int.Parse(value1);
cmd.Parameters.Add(param1);
}
using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input))
{
param2.Value = value2;
cmd.Parameters.Add(param2);
}
using (OracleDataReader dr = cmd.ExecuteReader())
{
// loop data here...
}
}
}
7 ответов
вы хотите избавиться от параметров только в самом конце их использования, в том числе во время запроса (и, возможно, чтения результатов):
using (OracleConnection conn = new OracleConnection(connectionstring))
{
conn.Open();
using (OracleCommand cmd = new OracleCommand(sql, conn))
{
cmd.BindByName = true;
using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input))
using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input))
{
param1.Value = int.Parse(value1);
cmd.Parameters.Add(param1);
param2.Value = value2;
cmd.Parameters.Add(param2);
using (OracleDataReader dr = cmd.ExecuteReader())
{
// loop data here...
}
}
}
}
обратите внимание, что вы можете поставить несколько using
высказывания подряд. Это потому, что, как if
заявление
- A
using
оператор считается простым оператором (даже с блоком); и - A
using
оператор может принимать либо блок, либо оператор нижний.
Я не уверен, что будет работать должным образом. Считайте, что в конце использования оба параметра должны были быть удалены. Дело в том, что ваш cmd.Parameters
объект по-прежнему держит ссылку на них не исключает того, что может происходить в OracleParameter
метод Dispose. Для всех интенсивных целей разработчик этого конкретного объекта может очищать поля, которые ваш OracleCommand
ожидается заполнение.
там какая-то опасность. Если вы абсолютно уверены, что хотите чтобы избавиться от OracleParameters
правильно, я предлагаю вам избавиться от них после OracleDataReader
использование.
помните, что обычно вы называете Dispose
когда вы закончите использовать объект. Вы говорите ему высвободить все ресурсы, которые он удерживает в бассейне. Если вы не закончили использовать объект, не избавляйтесь от него преждевременно.
using (OracleConnection conn = new OracleConnection(connectionstring))
using (OracleCommand cmd = new OracleCommand(sql, conn))
using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32,
System.Data.ParameterDirection.Input))
using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2,
System.Data.ParameterDirection.Input))
}
conn.Open();
cmd.BindByName = true;
param1.Value = int.Parse(value1);
cmd.Parameters.Add(param1);
param2.Value = value2;
cmd.Parameters.Add(param2);
using (OracleDataReader dr = cmd.ExecuteReader())
{
// loop data here...
}
}
нет это неправильно, потому что вы удаляете параметры еще до их использования.
вместо этого вы должны так это сделать
OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input);
param1.Value = int.Parse(value1);
cmd.Parameters.Add(param1);
OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input);
param2.Value = value2;
cmd.Parameters.Add(param2);
using (OracleDataReader dr = cmd.ExecuteReader())
{
// loop data here...
}
param1.dispose();
param2.dispose();
можете ли вы посмотреть исходный код соединения и команды, он распоряжается параметрами? если объект соединения или команды dispose pattern обертывает параметры и размещает их после их удаления. тебе стоит беспокоиться об этом. что, я думаю,было бы / должно быть.
этот код некорректен. созданные вами параметры по-прежнему используются вне using
область оператора, потому что вы добавляете их в коллекцию параметров, но using
заявление вызовет Dispose
параметры управления при выходе из области. Это означает, что, когда придет время использовать параметры внутри команды, theya будет уже disoised
по данным MSDN, вы должны использовать using
на Connection
и DataReader
объекты. Я никогда не видел using
(или .Dispose()
) используется с ADO.NET объекты параметров. Если бы это было необходимо или даже желательно, я думаю, что это произошло бы уже в течение последних 10 лет.