using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Threading; using Zhaizj.Framework.Web; using Zhaizj.Framework.ORM; using Zhaizj.Framework.ORM.Caching; namespace Zhaizj.Framework.Data { /// /// 数据库上下文,主要用于获取数据库连接 /// public class DbContext { /// /// 获取数据库连接,返回的连接已经打开(open);在 mvc 框架中不用关闭,框架会自动关闭连接。 /// 之所以要传入 Type,因为 ORM 支持多个数据库,不同的类型有可能映射到不同的数据库。 /// /// 实体的类型 /// public static IDbConnection getConnection( Type t ) { return getConnection( Entity.GetInfo( t ) ); } /// /// 获取数据库连接,返回的连接已经打开(open);在 mvc 框架中不用关闭,框架会自动关闭连接。 /// 之所以要传入 EntityInfo,因为 ORM 支持多个数据库,不同的类型有可能映射到不同的数据库。 /// /// /// public static IDbConnection getConnection( EntityInfo et ) { String db = et.Database; String connectionString = DbConfig.GetConnectionString( db ); IDbConnection connection; getConnectionAll().TryGetValue( db, out connection ); if (connection == null) { connection = DataFactory.GetConnection( connectionString, et.DbType ); connection.Open(); setConnection( db, connection ); if (shouldTransaction()) { IDbTransaction trans = connection.BeginTransaction(); setTransaction( db, trans ); } return connection; } if (connection.State == ConnectionState.Closed) { connection.ConnectionString = connectionString; connection.Open(); } return connection; } /// /// 关闭数据库连接。因为ORM支持多个数据库,所以所有可能的数据库连接都会一起关闭。 /// public static void closeConnectionAll() { ContextCache.Clear(); Dictionary dic = getConnectionAll(); foreach (KeyValuePair kv in dic) { IDbConnection connection = kv.Value; if ((connection != null) && (connection.State == ConnectionState.Open)) { connection.Close(); connection.Dispose(); } } freeItem( _connectionKey ); } //------------------------------------------------------------------------------ /// /// 获取所有的数据库连接 /// /// public static Dictionary getConnectionAll() { Dictionary dic; dic = CurrentRequest.getItem( _connectionKey ) as Dictionary; if (dic == null) { dic = new Dictionary(); CurrentRequest.setItem( _connectionKey, dic ); } return dic; } private static Dictionary getTransactionAll() { Dictionary dic; dic = CurrentRequest.getItem( _transactionKey ) as Dictionary; if (dic == null) { dic = new Dictionary(); CurrentRequest.setItem( _transactionKey, dic ); } return dic; } private static void setConnection( String key, IDbConnection cn ) { getConnectionAll()[key] = cn; } private static void setTransaction( String key, IDbTransaction trans ) { getTransactionAll()[key] = trans; } //------------------------------------------------------------------------------ public static void beginAndMarkTransactionAll() { CurrentRequest.setItem( _beginTransactionAll, true ); // 如果当前没有打开的数据库连接,则打上标记,等真正打开的时候启用事务 beginTransactionAll(); } private static bool shouldTransaction() { Object trans = CurrentRequest.getItem( _beginTransactionAll ); if (trans == null) return false; return (Boolean)trans; } /// /// 针对所有数据库连接,开启数据库事务 /// public static void beginTransactionAll() { Dictionary list = getConnectionAll(); foreach (KeyValuePair kv in list) { IDbTransaction trans = kv.Value.BeginTransaction(); setTransaction( kv.Key, trans ); } } public static void setTransaction( IDbCommand cmd ) { Dictionary transTable = getTransactionAll(); foreach (KeyValuePair kv in transTable) { IDbTransaction trans = kv.Value; if (cmd.Connection == trans.Connection) { cmd.Transaction = trans; return; } } } private static void clearTransactionAll() { Dictionary dic = CurrentRequest.getItem( _transactionKey ) as Dictionary; if (dic == null) return; dic.Clear(); CurrentRequest.setItem( _transactionKey, dic ); } /// /// 提交全部的数据库事务 /// public static void commitAll() { Dictionary transTable = getTransactionAll(); foreach (KeyValuePair kv in transTable) { IDbTransaction trans = kv.Value; if (trans != null && trans.Connection != null ) trans.Commit(); } clearTransactionAll(); } /// /// 回滚所有数据库事务 /// public static void rollbackAll() { Dictionary transTable = getTransactionAll(); foreach (KeyValuePair kv in transTable) { IDbTransaction trans = kv.Value; if (trans != null && trans.Connection != null) trans.Rollback(); } clearTransactionAll(); } //------------------------------------------------------------------------------ private static void freeItem( String key ) { if (!SystemInfo.IsWeb) { Thread.FreeNamedDataSlot( key ); } } internal static IDictionary getContextCache() { Object dic = CurrentRequest.getItem( _contextCacheKey ); if (dic == null) { dic = new Hashtable(); CurrentRequest.setItem( _contextCacheKey, dic ); } return dic as IDictionary; } /// /// 获取存储在上下文中的 sql 执行次数 /// /// public static int getSqlCount() { Object count = CurrentRequest.getItem( "sqlcount" ); if (count == null) return 0; return cvt.ToInt( count ); } private static readonly String _beginTransactionAll = "__beginTransactionAll"; private static readonly String _connectionKey = "__Zhaizj.FrameworkConnection"; private static readonly String _transactionKey = "__Zhaizj.FrameworkDbTransaction"; private static readonly String _contextCacheKey = "__contextCacheDictionary"; } }