/// <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); }
/// <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); }
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); } }
/// <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 ); } }
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); } }
public override void QueryList(IDbAccesser dba, IEntitySelectArgs args) { try { base.QueryList(dba, args); } catch (TooManyItemsInInClauseException) { /*********************** 代码块解释 ********************************* * 如果参数的个数过多,而当前的查询比较简单,那么就尝试分批使用参数进行查询。 * 这种情况主要出现在使用贪婪加载时,In 语句中的参数过多,但是查询本身非常简单,所以可以分批查询。 **********************************************************************/ if (!TryBatchQuery(dba, args)) { throw; } } }
/// <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 ); }
/// <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 ); } }
/// <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; }