Exemple #1
0
        /// <summary>
        /// 只有一些特定的查询,可以进行分批查询。
        /// </summary>
        /// <param name="dba">The dba.</param>
        /// <param name="args">The arguments.</param>
        /// <returns></returns>
        private bool TryBatchQuery(IDbAccesser dba, IEntitySelectArgs args)
        {
            if (!PagingInfo.IsNullOrEmpty(args.PagingInfo))
            {
                return(false);
            }

            //分批查询的条件:WHERE 条件中只有 IN 或 NOT IN 语句。
            var query    = args.Query;
            var inClause = query.Where as IColumnConstraint;

            if (inClause == null || inClause.Operator != PropertyOperator.In && inClause.Operator != PropertyOperator.NotIn)
            {
                return(false);
            }

            var values     = inClause.Value as IEnumerable;
            var parameters = values as IList ?? values.Cast <object>().ToArray();

            var autoSelection = AutoSelectionForLOB(query);

            var readType = autoSelection ? ReadDataType.ByIndex : ReadDataType.ByName;

            /*********************** 代码块解释 *********************************
             * 以下分批进行查询。算法:
             * 先临时把树中的条件中的值改成子集合,
             * 然后使用新的树生成对应的 Sql 语句并查询实体。
             * 所有查询完成后,再把树中的集合还原为原始的大集合。
             **********************************************************************/
            var maxItemsCount = SqlGenerator.CampatibleMaxItemsInInClause;
            var start         = 0;
            var paramSection  = new List <object>(maxItemsCount);

            inClause.Value = paramSection;//临时把树中的条件中的值改成子集合。
            while (start < parameters.Count)
            {
                paramSection.Clear();

                var end = Math.Min(start + maxItemsCount - 1, parameters.Count - 1);
                for (int i = start; i <= end; i++)
                {
                    paramSection.Add(parameters[i]);
                }

                //生成 Sql
                var generator = this.CreateSqlGenerator();
                QueryFactory.Instance.Generate(generator, query);
                var sql = generator.Sql;
                base.QueryDataReader(dba, args, readType, sql);

                start += paramSection.Count;
            }

            return(true);
        }
Exemple #2
0
        /// <summary>
        /// 使用 IQuery 条件进行查询。
        /// 分页默认实现为使用内存进行分页。
        /// </summary>
        /// <param name="dba">The dba.</param>
        /// <param name="args">The arguments.</param>
        public virtual void QueryList(IDbAccesser dba, IEntitySelectArgs args)
        {
            var query = args.Query;

            var autoSelection = AutoSelectionForLOB(query);

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

            this.QueryDataReader(dba, args, autoSelection ? ReadDataType.ByIndex : ReadDataType.ByName, sql);
        }
Exemple #3
0
        public override void QueryList(IDbAccesser dba, IEntitySelectArgs args)
        {
            /*********************** 代码块解释 *********************************
             *
             * 以下代码用于支持数据库分页
             *
             **********************************************************************/

            //检查分页条件。(如果是树状实体,也不支持在数据库中进行分页。)
            var  pagingInfo = args.PagingInfo;
            bool isPaging   = !PagingInfo.IsNullOrEmpty(pagingInfo) &&
                              this.GetPagingLocation(pagingInfo) == PagingLocation.Database &&
                              !Repository.SupportTree;

            if (isPaging)
            {
                var query = args.Query;
                if (!(query as TableQuery).HasOrdered())
                {
                    throw new InvalidProgramException("分页查询的同时,必须指定排序属性。");
                }

                var autoSelection = AutoSelectionForLOB(query);

                //生成分页 Sql
                var pk          = query.From.FindTable(Repository).Column(Entity.IdProperty);
                var generator   = this.CreateSqlGenerator();
                var pagedSelect = generator.ModifyToPagingTree(query as SqlSelect, pk as SqlColumn, pagingInfo);
                generator.Generate(pagedSelect);
                var pagingSql = generator.Sql;

                //查询数据库
                using (var reader = dba.QueryDataReader(pagingSql, pagingSql.Parameters))
                {
                    //填充到列表中。
                    this.FillDataIntoList(
                        reader, autoSelection ? ReadDataType.ByIndex : ReadDataType.ByName,
                        args.List, false, pagingInfo, args.MarkTreeFullLoaded
                        );
                }

                //最后,如果需要,则统计一下总行数。
                if (pagingInfo.IsNeedCount)
                {
                    pagingInfo.TotalCount = this.Count(dba, query);
                }
            }
            else
            {
                base.QueryList(dba, args);
            }
        }
Exemple #4
0
        public override void QueryList(IDbAccesser dba, IEntitySelectArgs args)
        {
            /*********************** 代码块解释 *********************************
             *
             * 以下代码用于支持数据库分页
             *
            **********************************************************************/

            //检查分页条件。(如果是树状实体,也不支持在数据库中进行分页。)
            var pagingInfo = args.PagingInfo;
            bool isPaging = !PagingInfo.IsNullOrEmpty(pagingInfo) &&
                this.GetPagingLocation(pagingInfo) == PagingLocation.Database &&
                !Repository.SupportTree;
            if (isPaging)
            {
                var query = args.Query;
                if (!(query as TableQuery).HasOrdered()) { throw new InvalidProgramException("分页查询的同时,必须指定排序属性。"); }

                var autoSelection = AutoSelectionForLOB(query);

                //生成分页 Sql
                var pk = query.From.FindTable(Repository).Column(Entity.IdProperty);
                var generator = this.CreateSqlGenerator();
                var pagedSelect = generator.ModifyToPagingTree(query as SqlSelect, pk as SqlColumn, pagingInfo);
                generator.Generate(pagedSelect);
                var pagingSql = generator.Sql;

                //查询数据库
                using (var reader = dba.QueryDataReader(pagingSql, pagingSql.Parameters))
                {
                    //填充到列表中。
                    this.FillDataIntoList(
                        reader, autoSelection ? ReadDataType.ByIndex : ReadDataType.ByName,
                        args.List, false, pagingInfo, args.MarkTreeFullLoaded
                        );
                }

                //最后,如果需要,则统计一下总行数。
                if (pagingInfo.IsNeedCount)
                {
                    pagingInfo.TotalCount = this.Count(dba, query);
                }
            }
            else
            {
                base.QueryList(dba, args);
            }
        }
Exemple #5
0
 /// <summary>
 /// 执行 Sql 并读取 DataReader 中的值到实体。
 /// </summary>
 /// <param name="dba">The dba.</param>
 /// <param name="args">The arguments.</param>
 /// <param name="readType">Type of the read.</param>
 /// <param name="sql">The SQL.</param>
 protected void QueryDataReader(IDbAccesser dba, IEntitySelectArgs args, ReadDataType readType, FormattedSql sql)
 {
     //查询数据库
     using (var reader = dba.QueryDataReader(sql, sql.Parameters))
     {
         //填充到列表中。
         this.FillDataIntoList(
             reader,
             readType,
             args.List,
             args.FetchingFirst,
             args.PagingInfo,
             args.MarkTreeFullLoaded
             );
     }
 }
Exemple #6
0
        public override void QueryList(IDbAccesser dba, IEntitySelectArgs args)
        {
            /*********************** 代码块解释 *********************************
             *
             * 以下代码用于支持数据库分页
             *
             **********************************************************************/

            //检查分页条件。(如果是树状实体,也不支持在数据库中进行分页。)
            var  pagingInfo = args.PagingInfo;
            bool isPaging   = !PagingInfo.IsNullOrEmpty(pagingInfo) &&
                              this.GetPagingLocation(pagingInfo) == PagingLocation.Database &&
                              !Repository.SupportTree;

            if (isPaging)
            {
                var query = args.Query;

                var autoSelection = AutoSelectionForLOB(query);

                //生成分页 Sql
                var generator = this.CreateSqlGenerator();
                generator.Generate(query as SqlSelect, pagingInfo);
                var pagingSql = generator.Sql;

                //查询数据库
                using (var reader = dba.QueryDataReader(pagingSql, pagingSql.Parameters))
                {
                    //填充到列表中。
                    this.FillDataIntoList(
                        reader, autoSelection ? ReadDataType.ByIndex : ReadDataType.ByName,
                        args.List, false, pagingInfo, args.MarkTreeFullLoaded
                        );
                }

                //最后,如果需要,则统计一下总行数。
                if (pagingInfo.IsNeedCount)
                {
                    pagingInfo.TotalCount = this.Count(dba, query);
                }
            }
            else
            {
                base.QueryList(dba, args);
            }
        }
Exemple #7
0
 public override void QueryList(IDbAccesser dba, IEntitySelectArgs args)
 {
     try
     {
         base.QueryList(dba, args);
     }
     catch (TooManyItemsInInClauseException)
     {
         /*********************** 代码块解释 *********************************
          * 如果参数的个数过多,而当前的查询比较简单,那么就尝试分批使用参数进行查询。
          * 这种情况主要出现在使用贪婪加载时,In 语句中的参数过多,但是查询本身非常简单,所以可以分批查询。
          **********************************************************************/
         if (!TryBatchQuery(dba, args))
         {
             throw;
         }
     }
 }
Exemple #8
0
        /// <summary>
        /// 使用 IQuery 条件进行查询。
        /// 分页默认实现为使用内存进行分页。
        /// </summary>
        /// <param name="dba">The dba.</param>
        /// <param name="args">The arguments.</param>
        public virtual void QueryList(IDbAccesser dba, IEntitySelectArgs args)
        {
            var query = args.Query;

            var autoSelection = AutoSelectionForLOB(query);

            var generator = this.CreateSqlGenerator();

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

            //查询数据库
            var reader = dba.QueryDataReader(sql, sql.Parameters);

            //填充到列表中。
            this.FillDataIntoList(
                reader, autoSelection ? ReadDataType.ByIndex : ReadDataType.ByName,
                args.List, args.FetchingFirst, args.PagingInfo, args.MarkTreeFullLoaded
                );
        }
Exemple #9
0
 /// <summary>
 /// 执行 Sql 并读取 DataReader 中的值到实体。
 /// </summary>
 /// <param name="dba">The dba.</param>
 /// <param name="args">The arguments.</param>
 /// <param name="readType">Type of the read.</param>
 /// <param name="sql">The SQL.</param>
 protected void QueryDataReader(IDbAccesser dba, IEntitySelectArgs args, ReadDataType readType, FormattedSql sql)
 {
     //查询数据库
     using (var reader = dba.QueryDataReader(sql, sql.Parameters))
     {
         //填充到列表中。
         this.FillDataIntoList(
             reader,
             readType,
             args.List,
             args.FetchingFirst,
             args.PagingInfo,
             args.MarkTreeFullLoaded
             );
     }
 }
Exemple #10
0
        /// <summary>
        /// 使用 IQuery 条件进行查询。
        /// 分页默认实现为使用内存进行分页。
        /// </summary>
        /// <param name="dba">The dba.</param>
        /// <param name="args">The arguments.</param>
        public virtual void QueryList(IDbAccesser dba, IEntitySelectArgs args)
        {
            var query = args.Query;

            var autoSelection = AutoSelectionForLOB(query);

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

            this.QueryDataReader(dba, args, autoSelection ? ReadDataType.ByIndex : ReadDataType.ByName, sql);
        }
Exemple #11
0
        /// <summary>
        /// 使用 IQuery 条件进行查询。
        /// 分页默认实现为使用内存进行分页。
        /// </summary>
        /// <param name="dba">The dba.</param>
        /// <param name="args">The arguments.</param>
        public virtual void QueryList(IDbAccesser dba, IEntitySelectArgs args)
        {
            var query = args.Query;

            var autoSelection = AutoSelectionForLOB(query);

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

            //查询数据库
            using (var reader = dba.QueryDataReader(sql, sql.Parameters))
            {
                //填充到列表中。
                this.FillDataIntoList(
                    reader, autoSelection ? ReadDataType.ByIndex : ReadDataType.ByName,
                    args.List, args.FetchingFirst, args.PagingInfo, args.MarkTreeFullLoaded
                    );
            }
        }
Exemple #12
0
 public override void QueryList(IDbAccesser dba, IEntitySelectArgs args)
 {
     try
     {
         base.QueryList(dba, args);
     }
     catch (TooManyItemsInInClauseException)
     {
         /*********************** 代码块解释 *********************************
          * 如果参数的个数过多,而当前的查询比较简单,那么就尝试分批使用参数进行查询。
          * 这种情况主要出现在使用贪婪加载时,In 语句中的参数过多,但是查询本身非常简单,所以可以分批查询。
         **********************************************************************/
         if (!TryBatchQuery(dba, args))
         {
             throw;
         }
     }
 }
Exemple #13
0
        /// <summary>
        /// 只有一些特定的查询,可以进行分批查询。
        /// </summary>
        /// <param name="dba">The dba.</param>
        /// <param name="args">The arguments.</param>
        /// <returns></returns>
        private bool TryBatchQuery(IDbAccesser dba, IEntitySelectArgs args)
        {
            if (!PagingInfo.IsNullOrEmpty(args.PagingInfo)) { return false; }

            //分批查询的条件:WHERE 条件中只有 IN 或 NOT IN 语句。
            var query = args.Query;
            var inClause = query.Where as IColumnConstraint;
            if (inClause == null || inClause.Operator != PropertyOperator.In && inClause.Operator != PropertyOperator.NotIn)
            {
                return false;
            }

            var values = inClause.Value as IEnumerable;
            var parameters = values as IList ?? values.Cast<object>().ToArray();

            var autoSelection = AutoSelectionForLOB(query);

            var readType = autoSelection ? ReadDataType.ByIndex : ReadDataType.ByName;

            /*********************** 代码块解释 *********************************
             * 以下分批进行查询。算法:
             * 先临时把树中的条件中的值改成子集合,
             * 然后使用新的树生成对应的 Sql 语句并查询实体。
             * 所有查询完成后,再把树中的集合还原为原始的大集合。
            **********************************************************************/
            var start = 0;
            var paramSection = new List<object>(MAX_ITEMS_IN_INCLAUSE);
            inClause.Value = paramSection;//临时把树中的条件中的值改成子集合。
            while (start < parameters.Count)
            {
                var end = Math.Min(start + MAX_ITEMS_IN_INCLAUSE - 1, parameters.Count - 1);
                paramSection.Clear();
                for (int i = start; i <= end; i++)
                {
                    paramSection.Add(parameters[i]);
                }

                //生成 Sql
                var generator = this.CreateSqlGenerator();
                QueryFactory.Instance.Generate(generator, query);
                var sql = generator.Sql;
                base.QueryDataReader(dba, args, readType, sql);

                start += paramSection.Count;
            }

            return true;
        }