向nuget发布8.7.2020.0308、9.16.2020.0308
大石头 authored at 2020-03-08 22:22:53
3.49 KiB
X
using System;
using System.Collections.Generic;
using System.Linq;
using NewLife.Collections;
using NewLife.Reflection;

namespace XCode.DataAccessLayer
{
    /// <summary>数据库工厂</summary>
    public static class DbFactory
    {
        #region 静态构造
        static DbFactory()
        {
            Register<SQLite>(DatabaseType.SQLite);
            Register<MySql>(DatabaseType.MySql);
            Register<Oracle>(DatabaseType.Oracle);
            Register<SqlServer>(DatabaseType.SqlServer);
            Register<PostgreSQL>(DatabaseType.PostgreSQL);
#if !__CORE__
            Register<Access>(DatabaseType.Access);
            Register<SqlCe>(DatabaseType.SqlCe);
#endif
            Register<Network>(DatabaseType.Network);
        }
        #endregion

        #region 提供者
        private static IDictionary<DatabaseType, IDatabase> _dbs = new NullableDictionary<DatabaseType, IDatabase>();
        /// <summary>注册数据库提供者</summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dbType"></param>
        public static void Register<T>(DatabaseType dbType) where T : IDatabase, new() => _dbs[dbType] = new T();

        /// <summary>根据数据库类型创建提供者</summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        public static IDatabase Create(DatabaseType dbType) => _dbs[dbType]?.GetType().CreateInstance() as IDatabase;

        /// <summary>根据名称获取默认提供者</summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        internal static IDatabase GetDefault(Type dbType) => _dbs.Values.FirstOrDefault(e => e.GetType() == dbType);

        internal static IDatabase GetDefault(DatabaseType dbType) => _dbs[dbType];
        #endregion

        #region 方法
        /// <summary>从提供者和连接字符串猜测数据库处理器</summary>
        /// <param name="connStr"></param>
        /// <param name="provider"></param>
        /// <returns></returns>
        public static Type GetProviderType(String connStr, String provider)
        {
            // 尝试从连接字符串获取优先提供者
            if (!connStr.IsNullOrWhiteSpace())
            {
                var builder = new ConnectionStringBuilder(connStr);
                if (builder.TryGetValue("provider", out var prv))
                {
                    foreach (var item in _dbs)
                    {
                        if (item.Value.Support(prv)) return item.Value.GetType();
                    }
                }
            }

            // 尝试解析提供者
            if (!provider.IsNullOrEmpty())
            {
                var n = 0;
                foreach (var item in _dbs)
                {
                    n++;

                    if (item.Value.Support(provider)) return item.Value.GetType();
                }

                if (DAL.Debug) DAL.WriteLog("无法从{0}个默认数据库提供者中识别到{1}!", n, provider);

                // 注册外部提供者
                var type = provider.GetTypeEx(true);
                if (type != null)
                {
                    var db = type.CreateInstance() as IDatabase;
                    if (db != null) _dbs[db.Type] = db;
                }

                return type;
            }

            // 默认SQLite
            return _dbs[DatabaseType.SQLite].GetType();
        }
        #endregion
    }
}