使用关键字的SqlDataAdapter

5

以下代码是否健康?或者我不需要使用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;
            }
        }
    }
}

我需要一些建议, 我正在研究使用DataReader技术,但一直在寻找使用using关键字以确保关闭连接的方法。然而,在使用DataReader时,如果我们想将其返回给某个方法,就不能使用该关键字,否则会关闭连接。 那么您认为以下技术对于DataReaderusing关键字是可行的吗:


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;
}

3
代码没有问题。在 DataAdapter.Fill 中,Connection 将会隐式地被打开/关闭。 - Tim Schmelter
2个回答

7

健康-问题不大;就我个人而言,使用 DataSetDataAdapter 可能是不健康的部分,但这可能只是我的个人偏见。

是的,在这里应该处理适配器等(这就是显然的 using 所做的工作)。

作为微不足道的整理,您可以堆叠 using - 这只是使其稍微简洁一些:

using (SqlConnection con = new SqlConnection(ConStr))
using (SqlCommand cmd = con.CreateCommand())
{

@MarkGravell,您能解释一下为什么适配器也应该被处理吗?SqlConnection的处理不够吗? - Alex
4
因为它实现了IDisposable接口,我们已经完成了使用它的任务。这已经足够的理由。其他细节上的内容我们应该避免讨论。作为用户,问题只需要归结为:”它是否实现了IDisposable接口?我是否已经使用完了它?” - Marc Gravell
@MarkGravell,正如您所提到的DataAdapter和DataSet可能会有问题,您是否意味着最好使用DataReader,将其映射到对象,关闭连接,最后返回模型对象而不是返回DataSet?您对此有何建议? - Akkad
@user2155873,我确实倾向于使用常规对象模型(而不是DataSet)。您如何与其交互取决于您:有无数的ORM工具可用。个人而言,我经常使用“dapper”,但这可能只是个人偏见。 - Marc Gravell

0

只留下第一个using就足够了(连接上的那个)因为处理连接将会处理所有需要处理的内容。

然而,处理所有内容也没有问题,只是需要多写一些代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接