Exemple #1
0
        /// <summary>获取提供者工厂</summary>
        /// <param name="assemblyFile"></param>
        /// <param name="className"></param>
        /// <returns></returns>
        protected static DbProviderFactory GetProviderFactory(String assemblyFile, String className)
        {
            var name     = Path.GetFileNameWithoutExtension(assemblyFile);
            var linkName = name;

            if (Runtime.Is64BitProcess)
            {
                linkName += "64";
            }
            var ver = Environment.Version;

            if (ver.Major >= 4)
            {
                linkName += "Fx" + ver.Major + ver.Minor;
            }
            // 有些数据库驱动不区分x86/x64,并且逐步以Fx4为主,所以来一个默认
            linkName += ";" + name;

            var type = PluginHelper.LoadPlugin(className, null, assemblyFile, linkName);

            // 反射实现获取数据库工厂
            var file = assemblyFile;

            file = NewLife.Setting.Current.GetPluginPath().CombinePath(file);

            // 如果还没有,就写异常
            if (type == null && !File.Exists(file))
            {
                throw new FileNotFoundException("缺少文件" + file + "!", file);
            }

            if (type == null)
            {
                XTrace.WriteLine("驱动文件{0}无效或不适用于当前环境,准备删除后重新下载!", assemblyFile);

                try
                {
                    File.Delete(file);
                }
                catch (UnauthorizedAccessException) { }
                catch (Exception ex) { XTrace.Log.Error(ex.ToString()); }

                type = PluginHelper.LoadPlugin(className, null, file, linkName);

                // 如果还没有,就写异常
                if (!File.Exists(file))
                {
                    throw new FileNotFoundException("缺少文件" + file + "!", file);
                }
            }
            if (type == null)
            {
                return(null);
            }

            var asm = type.Assembly;

            if (DAL.Debug)
            {
                DAL.WriteLog("{2}驱动{0} 版本v{1}", asm.Location, asm.GetName().Version, className.TrimEnd("Client", "Factory"));
            }

            var field = type.GetFieldEx("Instance");

            if (field == null)
            {
                return(Activator.CreateInstance(type) as DbProviderFactory);
            }

            return(Reflect.GetValue(null, field) as DbProviderFactory);
        }
Exemple #2
0
        /// <summary>获取提供者工厂</summary>
        /// <param name="assemblyFile"></param>
        /// <param name="className"></param>
        /// <param name="ignoreError"></param>
        /// <returns></returns>
        public static DbProviderFactory GetProviderFactory(String assemblyFile, String className, Boolean ignoreError = false)
        {
            try
            {
                var links = new List <String>();
                var name  = Path.GetFileNameWithoutExtension(assemblyFile);
                if (!name.IsNullOrEmpty())
                {
                    var linkName = name;
#if __CORE__
                    if (Runtime.Linux)
                    {
                        linkName += Environment.Is64BitProcess ? ".linux-x64" : ".linux-x86";
                        links.Add(linkName);
                        links.Add(name + ".linux");
                    }
                    else
                    {
                        linkName += Environment.Is64BitProcess ? ".win-x64" : ".win-x86";
                        links.Add(linkName);
                        links.Add(name + ".win");
                    }

                    linkName = name + ".st";
#else
                    if (Environment.Is64BitProcess)
                    {
                        linkName += "64";
                    }
                    var ver = Environment.Version;
                    if (ver.Major >= 4)
                    {
                        linkName += "Fx" + ver.Major + ver.Minor;
                    }
#endif
                    links.Add(linkName);
                    // 有些数据库驱动不区分x86/x64,并且逐步以Fx4为主,所以来一个默认
                    if (!links.Contains(name))
                    {
                        links.Add(name);
                    }
                }

                var type = PluginHelper.LoadPlugin(className, null, assemblyFile, links.Join(","));

                // 反射实现获取数据库工厂
                var file   = assemblyFile;
                var plugin = NewLife.Setting.Current.GetPluginPath();
                file = plugin.CombinePath(file);

                // 如果还没有,就写异常
                if (type == null)
                {
                    if (assemblyFile.IsNullOrEmpty())
                    {
                        return(null);
                    }
                    if (!File.Exists(file))
                    {
                        throw new FileNotFoundException("缺少文件" + file + "!", file);
                    }
                }

                if (type == null)
                {
                    XTrace.WriteLine("驱动文件{0}无效或不适用于当前环境,准备删除后重新下载!", assemblyFile);

                    try
                    {
                        File.Delete(file);
                    }
                    catch (UnauthorizedAccessException) { }
                    catch (Exception ex) { XTrace.Log.Error(ex.ToString()); }

                    type = PluginHelper.LoadPlugin(className, null, file, links.Join(","));

                    // 如果还没有,就写异常
                    if (!File.Exists(file))
                    {
                        throw new FileNotFoundException("缺少文件" + file + "!", file);
                    }
                }
                if (type == null)
                {
                    return(null);
                }

                var asm = type.Assembly;
                if (DAL.Debug)
                {
                    DAL.WriteLog("{2}驱动{0} 版本v{1}", asm.Location, asm.GetName().Version, name ?? className.TrimEnd("Client", "Factory"));
                }

                var field = type.GetFieldEx("Instance");
                if (field == null)
                {
                    return(Activator.CreateInstance(type) as DbProviderFactory);
                }

                return(Reflect.GetValue(null, field) as DbProviderFactory);
            }
            catch
            {
                if (ignoreError)
                {
                    return(null);
                }

                throw;
            }
        }
Exemple #3
0
        protected override void OnSetConnectionString(ConnectionStringBuilder builder)
        {
            base.OnSetConnectionString(builder);

            var flag = Factory != null && Factory.GetType().FullName.StartsWith("System.Data");

            if (flag)
            {
                //// 正常情况下INSERT, UPDATE和DELETE语句不返回数据。 当开启count-changes,以上语句返回一行含一个整数值的数据——该语句插入,修改或删除的行数。
                //if (!builder.ContainsKey("count_changes")) builder["count_changes"] = "1";

                // 优化SQLite,如果原始字符串里面没有这些参数,就设置这些参数
                //builder.TryAdd("Pooling", "true");
                //if (!builder.ContainsKey("Cache Size")) builder["Cache Size"] = "5000";
                builder.TryAdd("Cache Size", (512 * 1024 * 1024 / -1024) + "");
                // 加大Page Size会导致磁盘IO大大加大,性能反而有所下降
                //if (!builder.ContainsKey("Page Size")) builder["Page Size"] = "32768";
                // 这两个设置可以让SQLite拥有数十倍的极限性能,但同时又加大了风险,如果系统遭遇突然断电,数据库会出错,而导致系统无法自动恢复
                if (!Readonly)
                {
                    builder.TryAdd("Synchronous", "Off");
                }
                // Journal Mode的内存设置太激进了,容易出事,关闭
                //if (!builder.ContainsKey("Journal Mode")) builder["Journal Mode"] = "Memory";
                // 数据库中一种高效的日志算法,对于非内存数据库而言,磁盘I/O操作是数据库效率的一大瓶颈。
                // 在相同的数据量下,采用WAL日志的数据库系统在事务提交时,磁盘写操作只有传统的回滚日志的一半左右,大大提高了数据库磁盘I/O操作的效率,从而提高了数据库的性能。
                if (!Readonly)
                {
                    builder.TryAdd("Journal Mode", "WAL");
                }
                // 绝大多数情况下,都是小型应用,发生数据损坏的几率微乎其微,而多出来的问题让人觉得很烦,所以还是采用内存设置
                // 将来可以增加自动恢复数据的功能
                //if (!builder.ContainsKey("Journal Mode")) builder["Journal Mode"] = "Memory";

                if (Readonly)
                {
                    builder.TryAdd("Read Only", "true");
                }

                // 自动清理数据
                if (builder.TryGetAndRemove("autoVacuum", out var vac))
                {
                    AutoVacuum = vac.ToBoolean();
                }
            }
            //else
            //    SupportSchema = false;

            // 默认超时时间
            //if (!builder.ContainsKey("Default Timeout")) builder["Default Timeout"] = 5 + "";

            // 繁忙超时
            //var busy = Setting.Current.CommandTimeout;
            //if (busy > 0)
            {
                // SQLite内部和.Net驱动都有Busy重试机制,多次重试仍然失败,则会出现dabase is locked。通过加大重试次数,减少高峰期出现locked的几率
                // 繁忙超时时间。出现Busy时,SQLite内部会在该超时时间内多次尝试
                //if (!builder.ContainsKey("BusyTimeout")) builder["BusyTimeout"] = 50 + "";
                // 重试次数。SQLite.Net驱动在遇到Busy时会多次尝试,每次随机等待1~150ms
                //if (!builder.ContainsKey("PrepareRetries")) builder["PrepareRetries"] = 10 + "";
            }

            DAL.WriteLog(builder.ToString());
        }
Exemple #4
0
 /// <summary>输出日志</summary>
 /// <param name="format"></param>
 /// <param name="args"></param>
 public static void WriteLog(String format, params Object[] args) => DAL.WriteLog(format, args);
Exemple #5
0
        /// <summary>根据数据行取得数据表</summary>
        /// <param name="rows">数据行</param>
        /// <returns></returns>
        protected List <IDataTable> GetTables(DataRow[] rows)
        {
            //if (_columns == null) _columns = GetSchema(_.Columns, null);
            //if (_indexes == null) _indexes = GetSchema(_.Indexes, null);
            //if (_indexColumns == null) _indexColumns = GetSchema(_.IndexColumns, null);
            if (_columns == null)
            {
                try { _columns = GetSchema(_.Columns, null); }
                catch (Exception ex) { DAL.WriteDebugLog(ex.ToString()); }
            }
            if (_indexes == null)
            {
                try { _indexes = GetSchema(_.Indexes, null); }
                catch (Exception ex) { DAL.WriteDebugLog(ex.ToString()); }
            }
            if (_indexColumns == null)
            {
                try { _indexColumns = GetSchema(_.IndexColumns, null); }
                catch (Exception ex) { DAL.WriteDebugLog(ex.ToString()); }
            }

            try
            {
                DAL.WriteDebugLog("GetTables(Rows)- Foreach Start");

                List <IDataTable> list = new List <IDataTable>();
                foreach (DataRow dr in rows)
                {
                    #region 基本属性
                    IDataTable table = DAL.CreateTable();
                    table.Name = GetDataRowValue <String>(dr, _.TalbeName);

                    // 顺序、编号
                    Int32 id = 0;
                    if (TryGetDataRowValue <Int32>(dr, "TABLE_ID", out id))
                    {
                        table.ID = id;
                    }
                    else
                    {
                        table.ID = list.Count + 1;
                    }

                    // 描述
                    table.Description = GetDataRowValue <String>(dr, "DESCRIPTION");

                    // 拥有者
                    table.Owner = GetDataRowValue <String>(dr, "OWNER");

                    // 是否视图
                    table.IsView = String.Equals("View", GetDataRowValue <String>(dr, "TABLE_TYPE"), StringComparison.OrdinalIgnoreCase);

                    table.DbType = Database.DbType;
                    #endregion

                    #region 字段及修正
                    // 字段的获取可能有异常,但不应该影响整体架构的获取
                    try
                    {
                        var columns = GetFields(table);
                        if (columns != null && columns.Count > 0)
                        {
                            table.Columns.AddRange(columns);
                        }

                        var indexes = GetIndexes(table);
                        if (indexes != null && indexes.Count > 0)
                        {
                            table.Indexes.AddRange(indexes);
                        }

                        // 先修正一次关系数据
                        table.Fix();
                    }
                    catch (Exception ex)
                    {
                        if (DAL.Debug)
                        {
                            DAL.WriteLog(ex.ToString());
                        }
                    }

                    FixTable(table, dr);

                    list.Add(table);
                    #endregion
                }

                DAL.WriteDebugLog("GetTables(Rows)- Foreach End");

                #region 表间关系处理
                //// 某字段名,为另一个表的(表名+单主键名)形式时,作为关联字段处理
                //foreach (var table in list)
                //{
                //    foreach (var rtable in list)
                //    {
                //        if (table != rtable) table.Connect(rtable);
                //    }
                //}
                ModelHelper.Connect(list);

                //// 因为可能修改了表间关系,再修正一次
                //foreach (var table in list)
                //{
                //    table.Fix();
                //}
                #endregion

                return(list);
                // 不要把这些清空。因为,多线程同时操作的时候,前面的线程有可能把后面线程的数据给清空了
            }
            finally
            {
                _columns      = null;
                _indexes      = null;
                _indexColumns = null;
            }
        }
Exemple #6
0
 /// <summary>输出日志</summary>
 /// <param name="msg"></param>
 public static void WriteLog(String msg) => DAL.WriteLog(msg);
Exemple #7
0
        /// <summary>获取索引</summary>
        /// <param name="table"></param>
        /// <param name="indexes">索引</param>
        /// <param name="indexColumns">索引列</param>
        /// <returns></returns>
        protected virtual List <IDataIndex> GetIndexes(IDataTable table, DataTable indexes, DataTable indexColumns)
        {
            if (indexes == null)
            {
                return(null);
            }

            var drs = indexes.Select(String.Format("{0}='{1}'", _.TalbeName, table.TableName));

            if (drs == null || drs.Length < 1)
            {
                return(null);
            }

            var list = new List <IDataIndex>();

            foreach (var dr in drs)
            {
                if (!TryGetDataRowValue(dr, _.IndexName, out String name))
                {
                    continue;
                }

                var di = table.CreateIndex();
                di.Name = name;

                if (TryGetDataRowValue(dr, _.ColumnName, out name) && !String.IsNullOrEmpty(name))
                {
                    di.Columns = name.Split(",");
                }
                else if (indexColumns != null)
                {
                    String orderby = null;
                    // Oracle数据库用ColumnPosition,其它数据库用OrdinalPosition
                    if (indexColumns.Columns.Contains(_.OrdinalPosition))
                    {
                        orderby = _.OrdinalPosition;
                    }
                    else if (indexColumns.Columns.Contains(_.ColumnPosition))
                    {
                        orderby = _.ColumnPosition;
                    }

                    var dics = indexColumns.Select(String.Format("{0}='{1}' And {2}='{3}'", _.TalbeName, table.TableName, _.IndexName, di.Name), orderby);
                    if (dics != null && dics.Length > 0)
                    {
                        var ns = new List <String>();
                        foreach (var item in dics)
                        {
                            if (TryGetDataRowValue(item, _.ColumnName, out String dcname) && !dcname.IsNullOrEmpty() && !ns.Contains(dcname))
                            {
                                ns.Add(dcname);
                            }
                        }
                        if (ns.Count < 1)
                        {
                            DAL.WriteLog("表{0}的索引{1}无法取得字段列表!", table, di.Name);
                        }
                        di.Columns = ns.ToArray();
                    }
                }

                if (TryGetDataRowValue(dr, "UNIQUE", out Boolean b))
                {
                    di.Unique = b;
                }

                if (TryGetDataRowValue(dr, "PRIMARY", out b))
                {
                    di.PrimaryKey = b;
                }
                else if (TryGetDataRowValue(dr, "PRIMARY_KEY", out b))
                {
                    di.PrimaryKey = b;
                }

                FixIndex(di, dr);

                list.Add(di);
            }
            return(list != null && list.Count > 0 ? list : null);
        }
Exemple #8
0
        DataTable GetSchemaInternal(String key, String collectionName, String[] restrictionValues)
        {
            QueryTimes++;
            //// 如果启用了事务保护,这里要新开一个连接,否则MSSQL里面报错,SQLite不报错,其它数据库未测试
            //var isTrans = Transaction != null;

            //DbConnection conn = null;
            //if (isTrans)
            //{
            //    conn = Factory.CreateConnection();
            //    CheckConnStr();
            //    conn.ConnectionString = ConnectionString;
            //    conn.Open();
            //}
            //else
            //{
            //    if (!Opened) Open();
            //    conn = Conn;
            //}

            //// 连接未打开
            //if (conn.State == ConnectionState.Closed) return null;

            using (var pi = Database.Pool.AcquireItem())
            {
                var conn = pi.Value;
                //try
                //{
                DataTable dt = null;

                var sw = Stopwatch.StartNew();

                if (restrictionValues == null || restrictionValues.Length < 1)
                {
                    if (String.IsNullOrEmpty(collectionName))
                    {
                        WriteSQL("[" + Database.ConnName + "]GetSchema");
                        dt = conn.GetSchema();
                    }
                    else
                    {
                        WriteSQL("[" + Database.ConnName + "]GetSchema(\"" + collectionName + "\")");
                        dt = conn.GetSchema(collectionName);
                    }
                }
                else
                {
                    var sb = new StringBuilder();
                    foreach (var item in restrictionValues)
                    {
                        sb.Append(", ");
                        if (item == null)
                        {
                            sb.Append("null");
                        }
                        else
                        {
                            sb.AppendFormat("\"{0}\"", item);
                        }
                    }
                    WriteSQL("[" + Database.ConnName + "]GetSchema(\"" + collectionName + "\"" + sb + ")");
                    dt = conn.GetSchema(collectionName, restrictionValues);
                }

                sw.Stop();
                // 耗时超过多少秒输出错误日志
                if (sw.ElapsedMilliseconds > 1000)
                {
                    DAL.WriteLog("GetSchema耗时 {0:n0}ms", sw.ElapsedMilliseconds);
                }

                return(dt);
                //}
                //catch (DbException ex)
                //{
                //    throw new XDbSessionException(this, "取得所有表构架出错!", ex);
                //}
                //finally
                //{
                //    if (isTrans)
                //        conn.Close();
                //    else
                //        AutoClose();
                //}
            }
        }
Exemple #9
0
        DataTable GetSchemaInternal(String key, String collectionName, String[] restrictionValues)
        {
            QueryTimes++;
            // 如果启用了事务保护,这里要新开一个连接,否则MSSQL里面报错,SQLite不报错,其它数据库未测试
            var isTrans = TransactionCount > 0;

            DbConnection conn = null;

            if (isTrans)
            {
                conn = Factory.CreateConnection();
                checkConnStr();
                conn.ConnectionString = ConnectionString;
                conn.Open();
            }
            else
            {
                if (!Opened)
                {
                    Open();
                }
                conn = Conn;
            }

            try
            {
                DataTable dt;

                var sw = new Stopwatch();
                sw.Start();

                if (restrictionValues == null || restrictionValues.Length < 1)
                {
                    if (String.IsNullOrEmpty(collectionName))
                    {
                        WriteSQL("[" + Database.ConnName + "]GetSchema");
                        if (conn.State != ConnectionState.Closed) //ahuang 2013。06。25 当数据库连接字符串有误
                        {
                            dt = conn.GetSchema();
                        }
                        else
                        {
                            dt = null;
                        }
                    }
                    else
                    {
                        WriteSQL("[" + Database.ConnName + "]GetSchema(\"" + collectionName + "\")");
                        if (conn.State != ConnectionState.Closed)
                        {
                            dt = conn.GetSchema(collectionName);
                        }
                        else
                        {
                            dt = null;
                        }
                    }
                }
                else
                {
                    var sb = new StringBuilder();
                    foreach (var item in restrictionValues)
                    {
                        sb.Append(", ");
                        if (item == null)
                        {
                            sb.Append("null");
                        }
                        else
                        {
                            sb.AppendFormat("\"{0}\"", item);
                        }
                    }
                    WriteSQL("[" + Database.ConnName + "]GetSchema(\"" + collectionName + "\"" + sb + ")");
                    if (conn.State != ConnectionState.Closed)
                    {
                        dt = conn.GetSchema(collectionName, restrictionValues);
                    }
                    else
                    {
                        dt = null;
                    }
                }

                sw.Stop();
                // 耗时超过多少秒输出错误日志
                if (sw.ElapsedMilliseconds > 1000)
                {
                    DAL.WriteLog("耗时 {0:n0}ms", sw.ElapsedMilliseconds);
                }

                return(dt);
            }
            catch (DbException ex)
            {
                throw new XDbSessionException(this, "取得所有表构架出错!", ex);
            }
            finally
            {
                if (isTrans)
                {
                    conn.Close();
                }
                else
                {
                    AutoClose();
                }
            }
        }
Exemple #10
0
        DataTable GetSchemaInternal(String key, String collectionName, String[] restrictionValues)
        {
            QueryTimes++;
            // 如果启用了事务保护,这里要新开一个连接,否则MSSQL里面报错,SQLite不报错,其它数据库未测试
            var isTrans = TransactionCount > 0;

            DbConnection conn;

            if (isTrans)
            {
                try
                {
                    conn = Factory.CreateConnection();
                    conn.ConnectionString = ConnectionString;
                    conn.Open();
                }
                catch (DbException ex)
                {
                    DAL.WriteLog("错误的连接字符串:{0}", ConnectionString);
                    throw new XDbSessionException(this, "取得所有表构架出错!连接字符串有问题,请查看日志!", ex);
                }
            }
            else
            {
                if (!Opened)
                {
                    Open();
                }
                conn = Conn;
            }

            try
            {
                DataTable dt;

                if (restrictionValues == null || restrictionValues.Length < 1)
                {
                    if (String.IsNullOrEmpty(collectionName))
                    {
                        WriteSQL("GetSchema");
                        dt = conn.GetSchema();
                    }
                    else
                    {
                        WriteSQL("GetSchema(\"" + collectionName + "\")");
                        dt = conn.GetSchema(collectionName);
                    }
                }
                else
                {
                    var sb = new StringBuilder();
                    foreach (var item in restrictionValues)
                    {
                        sb.Append(", ");
                        if (item == null)
                        {
                            sb.Append("null");
                        }
                        else
                        {
                            sb.AppendFormat("\"{0}\"", item);
                        }
                    }
                    WriteSQL("GetSchema(\"" + collectionName + "\"" + sb + ")");
                    dt = conn.GetSchema(collectionName, restrictionValues);
                }

                return(dt);
            }
            catch (DbException ex)
            {
                throw new XDbSessionException(this, "取得所有表构架出错!", ex);
            }
            finally
            {
                if (isTrans)
                {
                    conn.Close();
                }
                else
                {
                    AutoClose();
                }
            }
        }