SqlDataAdapter с использованием ключевого слова

Является ли этот следующий код здоровым? Или мне не нужно использовать ключевое слово using, так как SqlDataAdapter будет обрабатывать закрытие соединения?

public static DataSet Fetch(string sp, SqlParameter [] prm)
{
    using (SqlConnection con = new SqlConnection(ConStr))
    {
        using (SqlCommand cmd = con.CreateCommand())
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = sp;
            cmd.Parameters.AddRange(prm);

            using (SqlDataAdapter dta = new SqlDataAdapter(cmd))
            {
                DataSet dst = new DataSet();
                dta.Fill(dst);

                return dst;
            }
        }
    }
}


@MarkGravell Мне нужны предложения, я действительно хочу использовать DataReader, но я все время искал ключевое слово using, чтобы обеспечить закрытие соединений. Где с DataReader мы не можем его использовать, потому что он закроет соединение, если мы захотим вернуть DataReader обратно какому-то методу. Итак, вы считаете, что следующая техника подходит для DataReader и ключевого слова using:

public static SqlDataReader Fetch(string sp, SqlParameter [] prm)
{
    SqlCommand cmd = new SqlConnection(ConStr).CreateCommand();
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.CommandText = sp;
    cmd.Parameters.AddRange(prm);
    cmd.Connection.Open();

    return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}

using (SqlDataReader dtrPrize = Sql.Fetch("SelectPrize", new SqlParameter[] { new SqlParameter("id", id) }))
{
    dtrPrize.Read();

    Prize prize = new Prize();
    prize.id = (int)dtrPrize[dtrPrize.GetOrdinal("id")];
    prize.artitle = (string)dtrPrize[dtrPrize.GetOrdinal("artitle")];
    prize.entitle = (string)dtrPrize[dtrPrize.GetOrdinal("entitle")];
    prize.ardetail = (string)dtrPrize[dtrPrize.GetOrdinal("ardetail")];
    prize.endetail = (string)dtrPrize[dtrPrize.GetOrdinal("endetail")];
    prize.image = (string)dtrPrize[dtrPrize.GetOrdinal("image")];
    prize.theme = (string)dtrPrize[dtrPrize.GetOrdinal("theme")];
    prize.price = (int)dtrPrize[dtrPrize.GetOrdinal("price")];
    prize.audience = (int)dtrPrize[dtrPrize.GetOrdinal("audience")];
    prize.type = (byte)dtrPrize[dtrPrize.GetOrdinal("type")];
    prize.status = (byte)dtrPrize[dtrPrize.GetOrdinal("status")];
    prize.voucher = (string)dtrPrize[dtrPrize.GetOrdinal("voucher")];
    prize.supplierid = (int)dtrPrize[dtrPrize.GetOrdinal("supplierid")];
    prize.created = (DateTime)dtrPrize[dtrPrize.GetOrdinal("created")];
    prize.updated = (DateTime)dtrPrize[dtrPrize.GetOrdinal("updated")];

    return prize;
}

person user2155873    schedule 11.03.2013    source источник
comment
Код в порядке. Connection будет открыто/закрыто неявно в DataAdapter.Fill.   -  person Tim Schmelter    schedule 11.03.2013


Ответы (2)


Здоровый; лично я бы сказал, что нездоровый бит — это тот, где используются DataSet и DataAdapter, но, возможно, это просто мое личное предубеждение.

Да, вы должны разместить адаптер и т. д. здесь (очевидно, что using делает для вас).

В качестве тривиальной бессмысленной приборки можно сложить usings — просто сделает чуть менее многословным:

using (SqlConnection con = new SqlConnection(ConStr))
using (SqlCommand cmd = con.CreateCommand())
{
person Marc Gravell    schedule 11.03.2013
comment
@MarkGravell Не могли бы вы объяснить, почему адаптер также следует утилизировать? Разве SqlConnection не достаточно? - person Alex; 11.03.2013
comment
@voo Потому что он реализует IDisposable, и с этим покончено. Это достаточная причина. Все, что выходит за рамки этого, относится к деталям реализации, которых нам следует избегать. Все, что нужно потребителю, это решить: реализует ли он IDisposable? Я закончил с этим? - person Marc Gravell; 11.03.2013
comment
@MarkGravell, как вы упомянули, что DataAdapter и DataSet могут быть неработоспособными, вы имеете в виду, что лучше использовать DataReader, сопоставить его с объектом, закрыть соединение и, наконец, вернуть объект модели, а не возвращать DataSet? Каковы ваши рекомендации здесь? - person user2155873; 11.03.2013
comment
@user2155873 user2155873 Здесь я действительно решительно склоняюсь к обычной объектной модели (а не к DataSet). Как вы с этим взаимодействуете, зависит от вас: существует множество доступных инструментов ORM. Лично я использую много щеголей, но это может быть просто личным предубеждением. - person Marc Gravell; 11.03.2013

Будет достаточно оставить только первый using (тот, что в соединении), потому что удаление соединения приведет к удалению всего, что вам нужно.

Тем не менее, нет ничего плохого в том, чтобы избавиться от всего, просто немного больше кода.

person Alon Catz    schedule 11.03.2013