我想知道在.Net应用程序中维护与数据库连接的最佳方法是什么(ADO.NET,但我想任何数据层的实践应该是相同的).我应该创建一个数据库连接并在我的应用程序中传播它,还是最好只需要传递连接字符串/工厂并创建一个ad-hoc连接.
据我所知,性能打击对于池并不显着,它允许我很容易地从断开的连接中恢复(只是创建一个新的连接)但是再一次连接对象是一个很好的,相对高级的抽象并创建一个新的连接对于每个操作(不是SQL命令,但是应用程序操作)会生成额外的重复代码,感觉就像浪费时间/资源(?).
您如何看待这两种情况,它们的缺点/优点以及您在实际应用中使用的方法是什么?
谢谢
我发现自己需要传递一个连接对象,所以我可以允许多个业务对象将自己保存到单个事务中的数据库中.
如果每个业务对象都必须为数据库创建自己的SQLConnection,那么事务将升级为分布式事务,我想避免这种情况.
我不喜欢将SQLConnection对象作为参数传递来保存对象,所以我创建了一个ConnectionManager来处理为我创建SQLConnection对象,跟踪SQLConnection对象的使用,以及在不使用时断开SQLConnection对象.
以下是一些代码作为ConnectionManager的示例:
public class ConnectionManager: IDisposable { private ConnectionManager instance; [ThreadStatic] private static object lockObject; private static Object LockObject { get { if (lockObject == null) lockObject = new object(); return lockObject; } } [ThreadStatic] private static Dictionarymanagers; private static Dictionary Managers { get { if (managers == null) managers = new Dictionary (); return managers; } } private SqlConnection connection = null; private int referenceCount; private string name; public static ConnectionManager GetManager(string connectionName) { lock (LockObject) { ConnectionManager mgr; if (Managers.ContainsKey(connectionName)) { mgr = Managers[connectionName]; } else { mgr = new ConnectionManager(connectionName); Managers.Add(connectionName, mgr); } mgr.AddRef(); return mgr; } } private ConnectionManager(string connectionName) { name = connectionName; connection = new SqlConnection(GetConnectionString(connectionName)); connection.Open(); } private string GetConnectionString(string connectionName) { string conString = Configuration.ConnectionString; return conString; } public SqlConnection Connection { get { return connection; } } private void AddRef() { referenceCount += 1; } private void DeRef() { lock (LockObject) { referenceCount -= 1; if (referenceCount == 0) { connection.Dispose(); Managers.Remove(name); } } } #region IDisposable Members public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing) { DeRef(); } } ~ConnectionManager() { Dispose(false); } #endregion }
以下是我将如何从业务对象中使用它:
public void Save() { using (ConnectionManager mrg = ConnectionManager.GetManager("SQLConnectionString") { using (SQLCommand cmd = new SQLCommand) { cmd.connection = mgr.Connection // More ADO Code Here } _childObject.Save(); //this child object follows the same pattern with a using ConnectionManager. } }
我保存了一个业务对象,并且使用相同的连接对象也保存了它的所有子节点.当范围远离原始父级时,using语句将关闭连接.
这是我从Rocky Lhotka在他的CSLA框架中学到的模式.
基思