在使用sqlcommand对象过程中,我们需要分配connection对象。 通常,对于大型的entity业务模型来说分配新的sqlconnection的操作非常频繁。要利用pool的优化功能,就要想到保持connection对象。由此想到可以把connection和transaction都保存到connectionproxy对象中。而此对象继承idisposable仅仅存在于一个request过程中。作为一个适用广泛的模型,我们建立executioncontext对象来封装对connectionproxy操作。
以下是connectionproxy代码:
internal class connectionproxy : idisposable
{
private string _connectionstring = null;
private sqlconnection _connection;
private sqltransaction _transaction;
private int _trancount = 0;
/// <summary>
/// constructs a new connectionproxy instance, setting the connection string
/// </summary>
/// <param name="connectionstring">a valid database connection string</param>
internal connectionproxy(string connectionstring)
{
_connectionstring = connectionstring;
}
/// <summary>
/// frees any connection related resources
/// </summary>
public void dispose()
{
// ensure that the connection does not have a pending transaction
if (_trancount != 0)
{
// rollback the transaction stack until the rollback already occurs
while (_trancount > 0) this.rollbacktransaction();
throw new dataaccessexception("dispose was called on a connection with a pending transaction. the transaction will be aborted.");
}
// close the connection if it is open
if ((_connection != null) && (_connection.state == connectionstate.open))
{
_connection.close();
}
_connection = null;
}
/// <summary>
/// gets the current connection object
/// </summary>
internal sqlconnection connection
{
get
{
// check that the connection string property has been set
if (_connectionstring == null)
{
//throw new dataaccessexception("connection string has not been set.");
}
// create new connection and open if one does not yet exist
if (_connection == null)
{
_connection = new sqlconnection(_connectionstring);
_connection.open();
//while (_connection.state == connectionstate.open) ;
}
return _connection;
}
}
/// <summary>
/// gets the current transaction context object
/// </summary>
internal sqltransaction transaction
{
get
{
return _transaction;
}
}
/// <summary>
/// begins a new transaction
/// </summary>
internal void begintransaction()
{
// only actually begin a new transaction if a transaction context does not yet exist
if (_trancount == 0)
{
// create new transaction context at the specified isolation level
_transaction = connection.begintransaction(isolationlevel.serializable);
}
_trancount++;
}
/// <summary>
/// commits a pending transaction
/// </summary>
internal void committransaction()
{
// check that a transaction context actually exists
if (_trancount <= 0) throw new dataaccessexception("no transaction is pending");
_trancount--;
// check if an actual commit should occur
if (_trancount == 0)
{
// if trancount is zero, but we dont have a transaction then something is wrong
if (_transaction == null)
{
throw (new dataaccessexception("transaction stack indicated a commit but no transaction exists!"));
}
// actually commit the transaction
_transaction.commit();
_transaction = null;
}
}
/// <summary>
/// rolls back a pending transaction
/// </summary>
internal void rollbacktransaction()
{
// check that a transaction context actually exists
if (_trancount <= 0) throw new dataaccessexception("no transaction is pending");
_trancount--;
// check if an actual rollback should occur
if (_trancount == 0)
{
// if trancount is zero, but we dont have a transaction then something is wrong
if (_transaction == null)
{
throw (new dataaccessexception("transaction stack indicated a rollback but no transaction exists!"));
}
// actually rollback the transaction
_transaction.rollback();
_transaction = null;
}
}
}
之后我们可以建立executioncontext.目的是使用这个proxy.当然也可以保存和使用其他的实例化对象:
public sealed class executioncontext
{
private static string connproxy = "connproxy";
private static string configproxy = "config";
private static connectionproxy _connproxy;
private static config _config;

/// <summary>
/// this class cannot be instantiated
/// </summary>
private executioncontext()
{
}
/// <summary>
///
/// </summary>
private static connectionproxy connectionproxy
{
get
{
if (httpcontext.current != null) //web app
return (connectionproxy)httpcontext.current.items[connproxy];
else
return _connproxy;
}
set
{
if(httpcontext.current != null) //web app
httpcontext.current.items.add(connproxy, value);
else
_connproxy = value;
}
}
private static config config
{
get
{
if (httpcontext.current != null) //web app
return (config)httpcontext.current.items[configproxy];
else
return _config;
}
set
{
if (httpcontext.current != null) //web app
httpcontext.current.items.add(configproxy, value);
else
_config = value;
}
}
/// <summary>
/// returns the connection object for the current execution context
/// </summary>
public static sqlconnection connection
{
get
{
assertinitialisation();
return connectionproxy.connection;
}
}
/// <summary>
/// returns the current transaction object for the current execution context
/// </summary>
public static sqltransaction transaction