public static Decimal ExecuteScalarDec(string procName, params object[] parameters) { try { using (Database database = DatabaseFactory.CreateDatabase()) { return (Decimal)database.ExecuteScalar(procName, parameters); } } catch (Exception ex) { throw new Exception(procName.ToString() + " " + parameters.ToString(), ex); } }
Update
OK, as this is EnterpriseLibrary code. The database class implements ExecuetScalar like this (other signatures will eventually crash):
public virtual object ExecuteScalar(DbCommand command) { if (command == null) throw new ArgumentNullException("command"); using (ConnectionWrapper wrapper = GetOpenConnection()) { PrepareCommand(command, wrapper.Connection); return DoExecuteScalar(command); } }
and ConnectionWrapper provides the connection (the end of the source file in the link), therefore, the theory goes, your call should be in order and delete the connection.
The GetOpenConnection () method returns a wrapper that removes the connection ... unless the current TransactionScopeConnections exists:
protected ConnectionWrapper GetOpenConnection(bool disposeInnerConnection) { DbConnection connection = TransactionScopeConnections.GetConnection(this); if (connection != null) { return new ConnectionWrapper(connection, false); } return new ConnectionWrapper(GetNewOpenConnection(), disposeInnerConnection); }
And this is how TransactionScopeConnections returns the connection:
public static DbConnection GetConnection(Database db) { Transaction currentTransaction = Transaction.Current; if (currentTransaction == null) return null; Dictionary<string, DbConnection> connectionList; DbConnection connection; lock (transactionConnections) { if (!transactionConnections.TryGetValue(currentTransaction, out connectionList)) {
Now, if I'm not mistaken, TransactionsScopeConnections will always create a new connection for a completely new database object (as in your case) and save the internal dictionary in it. The Database object does not implement a one-time, so I'm lost in determining who should clear the connections from this internal TransactionScopeConnecitons list.
Matt, is it possible to follow the next steps in this article about CLR leaks and see if there are a large number of database objects in your process? Download SOS and run !dumpheap -type Microsoft.Practices.EnterpriseLibrary.Data.Database . If you find many objects, can you track a stack of contacts on some of them with !gcroot <AddressOfObject>