C#SQL连接try / catch vs using vs try / catch w / using

时间:2015-11-24 16:31:54

标签: c# sql

我是第三代在我的组织内部工作的系统,当然编程风格也有所不同。我想知道连接数据库的正确方法是什么,因为系统中使用了两种不同的样式。那么"正确"方式是什么?

方法1:

try
{
    using (SqlConnection con = new SqlConnection(connectionString))
    {
        con.Open();

        using (SqlCommand command = new SqlCommand("StoredProcedure", con))
        {
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.Add(new SqlParameter("foo", bar));
        }

        using (SqlDataReader reader = command.ExecuteReader())
        {   
            //do stuff
        }
    }
}
catch (Exception ex)
{
    //do stuff
}

方法2:

// Variables
SqlCommand loComm;
SqlConnection loConn = null;
SqlDataReader loDR;

try
{
    // Init command
    loComm = new SqlCommand("foo");
    loComm.CommandType = CommandType.StoredProcedure;
    loComm.Parameters.AddWithValue("foo", bar);

    // Init conn
    loConn = new SqlConnection(String);
    loConn.Open();
    loComm.Connection = loConn;

    // Run command
    loDR = loComm.ExecuteReader();

    //do stuff           
}
catch (Exception ex)
{
    //do stuff
}

虽然两种方法都有效但我不确定哪种方法最适合使用。是否有理由使用其中一个?第二种方法对我来说更清晰,更容易理解,但它在完成时不会自动运行iDispose()函数。

编辑:我的问题与建议的问题不同,因为一种方法使用"使用"声明,而另一个没有。所以我的问题与是否使用"使用"直接相关。进行数据库连接时的语句。

感谢所有回复。

5 个答案:

答案 0 :(得分:14)

方法2不正确,应该修复。

完成后,您将留下尚未处置的IDisposable个实例。最有可能的是,这将对使用SqlConnection的幕后连接管理造成严重破坏,特别是如果此代码在GC决定介入之前遭受了很多破坏。

如果实例是IDisposable,那么它必须是Dispose d,最好是在尽可能小的范围内。使用using将确保发生这种情况,即使代码出现故障并引发异常。

using声明:

using(var disposableInstance = new SomeDisposableClass())
{
    //use your disposable instance
}

是(提供或采取一些小细节)语法糖:

var disposableInstance = new SomeDisposableClass();
try
{
    //use your disposable instance
}
finally
{
    //this will definitely run, even if there are exceptions in the try block
    disposableInstance.Dispose();
}

即使try块中出现问题,您也可以确保 finally块将被执行,从而确保您的一次性用品被处理掉,无论如何发生的情况。

答案 1 :(得分:1)

在第一个示例中,如果抛出异常,则using块中包含的对象将被正确关闭并处理。

在第二步中,您将手动处理对象。

另外值得一提的是,如果您计划仅在抛出异常时处理对象,则会有未被处置的对象,因此您需要实现try..catch..finally并处置finally块中的对象。

第一种是更好的选择。

答案 2 :(得分:0)

如果抛出异常,第一个将关闭连接。 第二个赢了,所以我说第一个选择。

答案 3 :(得分:0)

using块的作用是保证始终调用对象Dispose方法,无论是否抛出异常。

Dispose是一种用于清理资源的方法。在数据库连接的情况下,连接被释放,这非常重要。

因此,在这种情况下,正确的方法是使用using模式。

using父母之间包含的对象是IDisposable,这意味着它有一个Dispose方法,当不再需要该对象时应该调用该方法。如果你不调用dispose,当垃圾收集器销毁对象时,它将在任何不确定的时间处理。在数据库连接必须尽快关闭的情况下,这是不合需要的。

使用的等值是try finally,其中包含对Dispose块内finally的调用。

答案 4 :(得分:0)

阅读here,它说:

  

通常,当您使用IDisposable对象时,您应该在using语句中声明并实例化它。 using语句以正确的方式调用对象上的Dispose方法,并且(如前所示使用它时)一旦调用Dispose,它也会导致对象本身超出范围。在using块中,该对象是只读的,不能修改或重新分配。

using语句确保即使在对象上调用方法时发生异常,也会调用Dispose。您可以通过将对象放在try块中然后在finally块中调用Dispose来实现相同的结果;实际上,这就是编译器如何翻译using语句。

听起来正确的方法是方法1。