Exemplo n.º 1
0
        public override void Insert(IDbAccesser dba, Entity item)
        {
            //如果有 Id 列,那么需要在执行 Insert 的同时,执行 SELECT @@IDENTITY。
            //在为 SQL Server 插入数据时,执行 Insert 的同时,必须同时执行 SELECT @@IDENTITY。否则会有多线程问题。
            var idColumn = this.IdentityColumn;

            if (idColumn != null)
            {
                var    isIdentityHasValue = (item as IEntityWithId).IdProvider.IsAvailable(item.Id);
                string insertSql          = isIdentityHasValue ? _withIdInsertSql ?? (_withIdInsertSql = $" SET IDENTITY_INSERT {this.Name} ON ;{this.GenerateInsertSQL(true)};SET IDENTITY_INSERT {this.Name} OFF ;") :
                                            _insertSql ?? (_insertSql = $"{this.GenerateInsertSQL()};SELECT @@IDENTITY;");

                var parameters = Columns.Where(c => c.CanInsert || (c.Info.IsIdentity && isIdentityHasValue))
                                 .Select(c => c.ReadParameterValue(item))
                                 .ToArray();

                //由于默认是 decimal 类型,所以需要类型转换。
                var idValue = dba.QueryValue(insertSql, parameters);
                if (!isIdentityHasValue)
                {
                    idValue = TypeHelper.CoerceValue((item as IEntityWithId).IdProvider.KeyType, idValue);
                    idColumn.LoadValue(item, idValue);
                }

                //如果实体的 Id 是在插入的过程中生成的,
                //那么需要在插入组合子对象前,先把新生成的父对象 Id 都同步到子列表中。
                item.SyncIdToChildren();
            }
            else
            {
                base.Insert(dba, item);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 插入操作
        /// </summary>
        /// <param name="dba">数据库操作对象</param>
        /// <param name="item">要保存的实体对象</param>
        public override void Insert(IDbAccesser dba, Entity item)
        {
            var idColumn = this.IdentityColumn;

            if (idColumn != null)
            {
                var idProvider = (item as IEntityWithId).IdProvider;
                var hasId      = idProvider.IsAvailable(item.Id);

                string insertSql  = hasId ? _insertSqlWithId.Value : _insertSql.Value;
                var    parameters = this.GenerateInsertSqlParameters(item, hasId);

                var idValue = dba.QueryValue(insertSql, parameters);

                if (!hasId)
                {
                    idValue = TypeHelper.CoerceValue(idProvider.KeyType, idValue);
                    idColumn.WritePropertyValue(item, idValue);

                    //如果实体的 Id 是在插入的过程中生成的,
                    //那么需要在插入组合子对象前,先把新生成的父对象 Id 都同步到子列表中。
                    item.SyncIdToChildren();
                }
            }
            else
            {
                base.Insert(dba, item);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 如果需要统计,则生成统计语句进行查询。
        /// </summary>
        /// <param name="dba"></param>
        /// <param name="pagingInfo"></param>
        /// <param name="parts"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private static void QueryTotalCountIf(IDbAccesser dba, PagingInfo pagingInfo, PagingSqlParts parts, object[] parameters)
        {
            if (pagingInfo.IsNeedCount)
            {
                var pagingCountSql = "SELECT COUNT(0) " + parts.FromWhere;

                //查询值。(由于所有参数都不会在 OrderBy、Select 语句中,所以把所有参数都传入。
                var value = dba.QueryValue(pagingCountSql, parameters);
                pagingInfo.TotalCount = Convert.ToInt64(value);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// 获取指定大小批量的连续的 Id 号。返回第一个 Id 号的值。
        /// </summary>
        /// <param name="dba">数据操作对象</param>
        /// <param name="table">数据表对象</param>
        /// <returns></returns>
        private static long GetBatchIDs(IDbAccesser dba, RdbTable table)
        {
            var tableName = table.Name;

            lock (_identityLock)
            {
                var currentValue = Convert.ToInt64(dba.QueryValue(string.Format("SELECT IFNULL(MAX(id),0) FROM {0}", tableName)));
                return(currentValue);
            }

            throw new InvalidOperationException("生成 Id 时,发生未知错误。");
        }
Exemplo n.º 5
0
        /// <summary>
        /// 获取指定大小批量的连续的 Id 号。返回第一个 Id 号的值。
        /// </summary>
        /// <param name="dba">The dba.</param>
        /// <param name="table">The table.</param>
        /// <param name="size">需要连续的多少个 Id 号。</param>
        /// <returns></returns>
        private static long GetBatchIDs(IDbAccesser dba, RdbTable table, int size)
        {
            /*********************** 代码块解释 *********************************
             * 算法解释:
             * 1.先查出当前最大的 ID 值;
             * 2.计算出所需要使用的区间的起始、终止值 [start,end];
             * 3.然后设置 IDENTITY 的种子值为终止值;
             * 4.由于上两步 SQL 执行过程中有可能其它线程使用了这个 IDENTITY 而造成 [start,end] 中的值被使用,
             * 所以需要对表中的数据进行检测,如果没有被使用,才把这些 ID 值返回。
             * 如果被使用了,则上述过程重来一次即可。
             *
             * IDENTITY 的操作方法:http://www.cnblogs.com/gaizai/archive/2013/04/23/3038318.html
             **********************************************************************/

            var tableName = table.Name;

            lock (_identityLock)
            {
                while (true)
                {
                    var currentValue = Convert.ToInt64(dba.QueryValue(string.Format("SELECT IDENT_CURRENT('{0}')", tableName)));
                    var start        = currentValue + 1;
                    var end          = start + size - 1;
                    dba.ExecuteText(string.Format("DBCC CHECKIDENT('{0}', RESEED, {1})", tableName, end));

                    var concurrency = dba.QueryValue(string.Format(
                                                         "SELECT 1 WHERE EXISTS (SELECT 1 FROM {0} WHERE {1} >= {2} AND {1} <= {3})",
                                                         tableName, table.IdentityColumn.Name, start, end
                                                         ));
                    if (concurrency == null)
                    {
                        return(start);
                    }
                }
            }

            throw new InvalidOperationException("生成 Id 时,发生未知错误。");
        }
Exemplo n.º 6
0
        internal long Count(IDbAccesser dba, IQuery query)
        {
            var oldCounting = query.IsCounting;
            try
            {
                query.IsCounting = true;

                var generator = this.CreateSqlGenerator();
                QueryFactory.Instance.Generate(generator, query);
                var sql = generator.Sql;

                var value = dba.QueryValue(sql, sql.Parameters);
                return ConvertCount(value);
            }
            finally
            {
                query.IsCounting = oldCounting;
            }
        }
Exemplo n.º 7
0
        public override void Insert(IDbAccesser dba, Entity item)
        {
            //如果有 Id 列,那么需要在执行 Insert 的同时,执行 SELECT @@IDENTITY。
            //在为 SQL Server 插入数据时,执行 Insert 的同时,必须同时执行 SELECT @@IDENTITY。否则会有多线程问题。
            var idColumn = this.IdentityColumn;

            if (idColumn != null)
            {
                if (_insertSQL == null)
                {
                    _insertSQL  = this.GenerateInsertSQL();
                    _insertSQL += Environment.NewLine;
                    _insertSQL += "SELECT @@IDENTITY;";
                }

                var parameters = new List <object>();
                foreach (RdbColumn column in this.Columns)
                {
                    if (column.CanInsert)
                    {
                        var value = column.ReadParameterValue(item);
                        parameters.Add(value);
                    }
                }

                //由于默认是 decimal 类型,所以需要类型转换。
                var idValue = dba.QueryValue(this._insertSQL, parameters.ToArray());
                idValue = TypeHelper.CoerceValue((item as IEntityWithId).IdProvider.KeyType, idValue);
                idColumn.LoadValue(item, idValue);

                //如果实体的 Id 是在插入的过程中生成的,
                //那么需要在插入组合子对象前,先把新生成的父对象 Id 都同步到子列表中。
                item.SyncIdToChildren();
            }
            else
            {
                base.Insert(dba, item);
            }
        }
Exemplo n.º 8
0
        public override void Insert(IDbAccesser dba, Entity item)
        {
            //如果有 Id 列,那么需要在执行 Insert 的同时,执行 SELECT @@IDENTITY。
            //在为 SQL Server 插入数据时,执行 Insert 的同时,必须同时执行 SELECT @@IDENTITY。否则会有多线程问题。
            var idColumn = this.IdentityColumn;
            if (idColumn != null)
            {
                if (_insertSQL == null)
                {
                    _insertSQL = this.GenerateInsertSQL();
                    _insertSQL += Environment.NewLine;
                    _insertSQL += "SELECT @@IDENTITY;";
                }

                var parameters = new List<object>();
                foreach (RdbColumn column in this.Columns)
                {
                    if (column.CanInsert)
                    {
                        var value = column.ReadParameterValue(item);
                        parameters.Add(value);
                    }
                }

                //由于默认是 decimal 类型,所以需要类型转换。
                var idValue = dba.QueryValue(this._insertSQL, parameters.ToArray());
                idValue = TypeHelper.CoerceValue(item.KeyProvider.KeyType, idValue);
                idColumn.LoadValue(item, idValue);

                //如果实体的 Id 是在插入的过程中生成的,
                //那么需要在插入组合子对象前,先把新生成的父对象 Id 都同步到子列表中。
                item.SyncIdToChildren();
            }
            else
            {
                base.Insert(dba, item);
            }
        }
        protected override void RunCore(IDbAccesser db)
        {
            var count = Convert.ToInt32(db.QueryValue(
                                            "SELECT COUNT(0) FROM ALL_SEQUENCES WHERE SEQUENCE_NAME = {0} AND SEQUENCE_OWNER = {1}",
                                            this.SequenceName,
                                            DbConnectionSchema.GetOracleUserId(db.ConnectionSchema).ToUpper()
                                            ));

            if (count <= 0)
            {
                db.ExecuteText(string.Format(
                                   @"CREATE SEQUENCE {0}
MINVALUE 1
MAXVALUE 99999999999999999
START WITH 1
INCREMENT BY 1
NOCACHE
ORDER", this.SequenceName));
            }

            //            var sql = string.Format(@"DECLARE T_COUNT NUMBER;
            //BEGIN
            //    SELECT COUNT(*) INTO T_COUNT FROM DUAL WHERE EXISTS(SELECT * FROM ALL_SEQUENCES WHERE SEQUENCE_NAME='{0}');
            //    IF T_COUNT = 0 THEN
            //        EXECUTE IMMEDIATE '
            //        CREATE SEQUENCE {0}
            //        MINVALUE 1
            //        MAXVALUE 99999999999999999
            //        START WITH 1
            //        INCREMENT BY 1
            //        NOCACHE
            //        ORDER
            //        ';
            //    END IF;
            //END;", this.SEQName(op));
        }
Exemplo n.º 10
0
        internal int Count(IDbAccesser dba, IQuery query)
        {
            var oldCounting = query.IsCounting;
            try
            {
                query.IsCounting = true;

                var generator = this.CreateSqlGenerator();
                QueryFactory.Instance.Generate(generator, query);
                var sql = generator.Sql;

                var value = dba.QueryValue(sql, sql.Parameters);
                return ConvertCount(value);
            }
            finally
            {
                query.IsCounting = oldCounting;
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// 如果需要统计,则生成统计语句进行查询。
        /// </summary>
        /// <param name="dba"></param>
        /// <param name="pagingInfo"></param>
        /// <param name="parts"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private static void QueryTotalCountIf(IDbAccesser dba, PagingInfo pagingInfo, PagingSqlParts parts, object[] parameters)
        {
            if (pagingInfo.IsNeedCount)
            {
                var pagingCountSql = "SELECT COUNT(0) " + parts.FromWhere;

                //查询值。(由于所有参数都不会在 OrderBy、Select 语句中,所以把所有参数都传入。
                var value = dba.QueryValue(pagingCountSql, parameters);
                pagingInfo.TotalCount = Convert.ToInt32(value);
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// 获取指定大小批量的连续的 Id 号。返回第一个 Id 号的值。
        /// </summary>
        /// <param name="dba">The dba.</param>
        /// <param name="table">The table.</param>
        /// <param name="size">需要连续的多少个 Id 号。</param>
        /// <returns></returns>
        private static int GetBatchIDs(IDbAccesser dba, RdbTable table, int size)
        {
            /*********************** 代码块解释 *********************************
             * 算法解释:
             * 1.先查出当前最大的 ID 值;
             * 2.计算出所需要使用的区间的起始、终止值 [start,end];
             * 3.然后设置 IDENTITY 的种子值为终止值;
             * 4.由于上两步 SQL 执行过程中有可能其它线程使用了这个 IDENTITY 而造成 [start,end] 中的值被使用,
             * 所以需要对表中的数据进行检测,如果没有被使用,才把这些 ID 值返回。
             * 如果被使用了,则上述过程重来一次即可。
             *
             * IDENTITY 的操作方法:http://www.cnblogs.com/gaizai/archive/2013/04/23/3038318.html
            **********************************************************************/

            var tableName = table.Name;

            lock (_identityLock)
            {
                while (true)
                {
                    var currentValue = Convert.ToInt32(dba.QueryValue(string.Format("SELECT IDENT_CURRENT('{0}')", tableName)));
                    var start = currentValue + 1;
                    var end = start + size - 1;
                    dba.ExecuteText(string.Format("DBCC CHECKIDENT('{0}', RESEED, {1})", tableName, end));

                    var concurrency = dba.QueryValue(string.Format(
                        "SELECT 1 WHERE EXISTS (SELECT 1 FROM {0} WHERE {1} >= {2} AND {1} <= {3})",
                        tableName, table.IdentityColumn.Name, start, end
                        ));
                    if (concurrency == null) return start;
                }
            }

            throw new InvalidOperationException("");
        }