【发布时间】:2013-03-28 03:09:00
【问题描述】:
我有一个用于进行数据库调用的 Linq-to-SQL DataClasses 对象。我是这样包装的:
public class DataWrapper {
private DataClassesDataContext _connection = null;
private static DataWrapper _instance = null;
private const string PROD_CONN_STR = "Data Source=proddb;Initial Catalog=AppName;User ID=sa;Password=pass; MultipleActiveResultSets=true;Asynchronous Processing=True";
public static DataClassesDataContext Connection {
get {
if (Instance._connection == null)
Instance._connection = new DataClassesDataContext(DEV_CONN_STR);
return Instance._connection;
}
}
private static DataWrapper Instance {
get {
if (_instance == null) {
_instance = new DataWrapper();
}
return _instance;
}
}
}
我有几个线程使用这个包装器进行存储过程调用,如下所示:
DataWrapper.Connection.Remove_Message(completeMessage.ID);
在极少数情况下,我的 DataClasses 对象会抛出异常:
ExecuteNonQuery 需要一个开放且可用的连接。这 连接的当前状态为关闭。
我没有以任何方式管理连接的状态——我认为 Linq-to-SQL 应该处理这个问题。我可以在每次拨打电话时检查 Connection 的连接状态,如果它已关闭则打开它,但这似乎是一种黑客攻击。
我尝试将MultipleActiveResultSets=true 和Asynchronous Processing=True 放在连接字符串上,以尝试处理SQL 强制关闭连接的可能性,但这似乎没有帮助。
有什么想法吗?
【问题讨论】:
-
为什么不打开连接,进行调用,然后关闭连接,让底层 ADO.NET 处理连接池?您没有为实际调用发布任何代码 - 我认为带有上下文的简单 using 块将负责关闭部分。我在 EF 上玩的不多,所以我可能会在这里离场。
-
让我猜猜,这是网络应用程序...
-
@Tim 我不知道。我不这么认为。 Jon Skeet 的回答 here 似乎暗示 DataClasses 对象应该足够聪明来处理它。
-
@leppie 不,这是一个 WPF 应用程序。
-
@Doc:是的。
ThreadStatic将解决这种情况下的问题。对于ThreadStatic,请记住_instance在每个线程上最初都会为空(除非在某个时候通过静态构造函数分配,但这只会发生一次,而不是每个线程)。 IIRC,DataContext在 LINQ2SQL 中按需打开/关闭连接(如果尚未打开)。
标签: c# sql-server linq-to-sql