using System; using System.Collections.Generic; using System.Text; using Zhaizj.Framework.ORM; using Zhaizj.Framework.Reflection; using Zhaizj.Framework.Serialization; using Zhaizj.Framework.Web; using System.IO; using System.Web; using Zhaizj.Framework.IO; using Zhaizj.Framework.Data.Config; namespace Zhaizj.Framework.Data { /// /// 数据库连接字符串内容的封装 /// public class ConnectionString { public String Name { get; set; } public String StringContent { get; set; } public DatabaseType DbType { get; set; } } /// /// ORM 的数据库配置 /// public class DbConfig { private static readonly ILog logger = LogManager.GetLogger( typeof( DbConfig ) ); public DbConfig() { this.ConnectionStringTable = new Dictionary(); this.AssemblyList = new List(); this.DbType = new Dictionary(); this.IdType = Zhaizj.Framework.Data.IdType.Auto; this.Interceptor = new List(); this.IsCheckDatabase = true; this.ContextCache = true; this.Mapping = new List(); } /// /// 默认数据库名称(值为default) /// public static readonly String DefaultDbName = "default"; /// /// 配置的缓存内容(单例模式缓存) /// public static DbConfig Instance = loadConfig( getConfigPath() ); /// /// 直接解析json的结果:多个数据库连接字符串(connectionString)的键值对 /// public Dictionary ConnectionStringTable { get; set; } private Dictionary _connectionStringMap = new Dictionary(); /// /// 多个数据库连接字符串对象的map,值是ConnectionString对象(包括Name/StringContent/DbType) /// /// public Dictionary GetConnectionStringMap() { return _connectionStringMap; } internal void SetConnectionStringMap( Dictionary cmap ) { _connectionStringMap = cmap; } /// /// 直接解析json的结果:数据库类型 /// public Dictionary DbType { get; set; } /// /// 实体键值类型 /// public String IdType { get; set; } /// /// 自动键值 /// [NotSerialize] public bool IsAutoId { get { return IdType.Equals(Zhaizj.Framework.Data.IdType.Auto, StringComparison.OrdinalIgnoreCase); } } /// /// 直接解析json的结果:程序集列表 /// public List AssemblyList { get; set; } /// /// 是否坚持数据库,如果检查,则会将尚未创建的数据表自动创建 /// public Boolean IsCheckDatabase { get; set; } /// /// 数据表的前缀(默认没有前缀) /// public String TablePrefix { get; set; } /// /// 是否开启一级缓存,默认开启,并且建议开启 /// public Boolean ContextCache { get; set; } /// /// 是否开启二级缓存 /// public Boolean ApplicationCache { get; set; } /// /// 二级缓存的时间(分钟) /// public int ApplicationCacheMinutes { get; set; } /// /// 二级缓存管理程序,请填写类型(type)的全名(full name),比如 Zhaizj.Framework.somens.myCache; /// 如果不填写,则使用默认的System.Web.Caching /// public String ApplicationCacheManager { get; set; } /// /// ORM 的元数据文件名称,一般不需填写(建议不要填写)。如果为了提高网站启动时候的速度,可以填写。 /// 系统会根据文件名自动生成元数据文件,可以避免以后网站启动过程中的反射,能略微提高启动速度; /// 文件名不包括路径(必须放在bin目录中),比如 Zhaizj.Framework.meta.dll /// public String MetaDLL { get; set; } /// /// 直接解析json的结果:数据表映射 /// public List Mapping { get; set; } /// /// 拦截器列表 /// public List Interceptor { get; set; } /// /// 反射优化模式,目前只实现了 CodeDom 方式 /// [NotSerialize] internal OptimizeMode OptimizeMode { get { return OptimizeMode.CodeDom; } set { } } /// /// 获取元数据库文件的绝对路径 /// /// public String GetMetaDllAbsPath() { if (strUtil.IsNullOrEmpty( this.MetaDLL )) return ""; String dllPath = this.MetaDLL; if (dllPath.ToLower().EndsWith( ".dll" ) == false) dllPath = dllPath + ".dll"; dllPath = Path.Combine( PathTool.GetBinDirectory(), dllPath ); return dllPath; } private Dictionary _mappings = new Dictionary(); private void addMapping( MappingInfo mi ) { _mappings.Add( mi.TypeName, mi ); } /// /// 获取映射信息 /// /// internal Dictionary GetMappingInfo() { return _mappings; } //---------------------------------------------------------------------- private static DbConfig loadConfig( String cfgPath ) { String str = SectionDataHandler.Current.GetDataConfig();//file.Read( cfgPath ); DbConfig dbc = JSON.ToObject( str ); loadMappingInfo( dbc ); checkConnectionString( dbc ); return dbc; } private static void loadMappingInfo( DbConfig dbc ) { if (dbc.Mapping.Count == 0) return; foreach (Dictionary dic in dbc.Mapping) { MappingInfo mi = new MappingInfo(); if (dic.ContainsKey( "name" )) mi.TypeName = dic["name"].ToString(); if (dic.ContainsKey( "database" )) mi.Database = dic["database"].ToString(); if (dic.ContainsKey( "table" )) mi.Table = dic["table"].ToString(); dbc.addMapping( mi ); } } private static String getConfigPath() { return PathHelper.Map( strUtil.Join( cfgHelper.ConfigRoot, "orm.config" ) ); } private static void checkConnectionString( DbConfig result ) { logger.Info( "checkConnectionString..." ); if (result.ConnectionStringTable == null) return; Dictionary connStringMap = new Dictionary(); Dictionary newString = new Dictionary(); foreach (KeyValuePair kv in result.ConnectionStringTable) { String connectionString = kv.Value.ToString(); DatabaseType dbtype = getDbType( kv.Key, connectionString, result ); ConnectionString objConnString = new ConnectionString { Name = kv.Key, StringContent = connectionString, DbType = dbtype }; connStringMap.Add( kv.Key, objConnString ); logger.Info( "connectionString:" + connectionString ); IDatabaseDialect dialect = DataFactory.GetDialect( dbtype ); if ((dbtype == DatabaseType.Access)) { String connectionItem = dialect.GetConnectionItem( connectionString, ConnectionItemType.Database ); logger.Info( "database path original:" + connectionItem ); if (IsRelativePath( connectionItem )) { connectionItem = PathHelper.Map( strUtil.Join( SystemInfo.ApplicationPath, connectionItem ) ); logger.Info( "database path now:" + connectionItem ); String newConnString = String.Format( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", connectionItem ); newString.Add( kv.Key, newConnString ); } } } foreach (KeyValuePair kv in newString) { result.ConnectionStringTable[kv.Key] = kv.Value; connStringMap[kv.Key].StringContent = kv.Value; } result.SetConnectionStringMap( connStringMap ); } private static bool IsRelativePath( string connectionItem ) { return connectionItem.IndexOf( ":" ) < 0; } private static DatabaseType getDbType( String dbname, String connectionString, DbConfig result ) { foreach (KeyValuePair kv in result.DbType) { if (kv.Key == dbname) return DbTypeChecker.GetFromString( kv.Value.ToString() ); } DatabaseType dbtype = DbTypeChecker.GetDatabaseType( connectionString ); return dbtype; } //---------------------------------------------------------------------- /// /// 根据命名,获取数据库连接字符串 /// /// /// public static String GetConnectionString( String db ) { if (DbConfig.Instance.ConnectionStringTable.ContainsKey( db ) == false) throw new Exception( lang.get( "dbNotExist" ) + ": " + db ); return (String)DbConfig.Instance.ConnectionStringTable[db]; } internal static void SaveConnectionString( String connectionString ) { String cfgPath = getConfigPath(); if (DbConfig.Instance.ConnectionStringTable == null) DbConfig.Instance.ConnectionStringTable = new Dictionary(); DbConfig.Instance.ConnectionStringTable[DefaultDbName] = connectionString; String str = JsonString.ConvertObject( DbConfig.Instance, true ); file.Write( cfgPath, str ); } } }