这很有意思(无论如何),我想看看是否有人对这种行为有一个很好的答案和解释。
假设你有一个单例数据库对象(或静态数据库对象),并将它存储在类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,但包含空属性。
为什么会这样?
答案 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);
}
}