在static / singleton资源引用周围使用块

时间:2010-05-21 06:26:36

标签: c# singleton using

这很有意思(无论如何),我想看看是否有人对这种行为有一个很好的答案和解释。

假设你有一个单例数据库对象(或静态数据库对象),并将它存储在类Foo中。

public class Foo
{
    public static SqlConnection DBConn = new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString);
}

然后,让我们说你已经认识到调用和处理你的连接的有用性(假装这个例子它是一次性用于说明的目的)。因此,您决定使用“使用”块来处理Dispose()调用。

using (SqlConnection conn = Foo.DBConn)
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand())
    {
        cmd.Connection = conn;
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
        cmd.CommandText = "SP_YOUR_PROC";

        cmd.ExecuteNonQuery();
    }
    conn.Close();
}

此操作失败,在打开连接的调用上抛出异常,声明“ConnectionString属性未初始化”。从app.config / web.config中提取连接字符串不是问题。在调试会话中进行调查时,您会看到Foo.DBConn不为null,但包含空属性。

为什么会这样?

3 个答案:

答案 0 :(得分:2)

有点偏离主题,并没有真正回答你的问题,但为什么在ADO.NET已经使用连接池时使用单例进行SqlConnection?你的代码看起来很像:

using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.Connection = conn;
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.CommandText = "SP_YOUR_PROC";
    cmd.ExecuteNonQuery();
}

在你的程序中要少担心一件事:连接生命周期

答案 1 :(得分:0)

也许您在web / app.config中没有相应的connectionStrings节点?

<connectionStrings>
<add name="BAR"
     connectionString="Data Source=localhost\sqlexpress;Initial Catalog=mydatabase;User Id=myuser;Password=mypassword;" />

答案 2 :(得分:-1)

静态字段在使用之前某时 (非确定性)。有关详细信息,请参阅beforefieldinit。因此,在调用它时,系统可能还没有为创建SQL连接做好准备,或者甚至可以在之后正确创建静态字段

此外,关闭第一个SQL命令后,如何处理第二个SQL命令?我不确切知道SqlConnection是如何工作的,但在关闭之后(注意这个cals Dispose)并处理连接,你的静态Foo.DBConn应该消失,即它不会被重新评估。

如果你想保留你的基础架构,我会用静态属性替换静态字段,该属性在get上返回一个新的SqlConnection:

public static SqlConnection DBConn
{
    get
    {
        return new SqlConnection(ConfigurationManager.ConnectionStrings["BAR"].ConnectionString);
    }
}