Пример #1
0
        /// <summary>
        /// 通过 IQuery 对象来查询实体。
        /// </summary>
        /// <param name="args">The arguments.</param>
        /// <returns></returns>
        /// <exception cref="System.NotSupportedException">使用内存过滤器的同时,不支持提供分页参数。</exception>
        /// <exception cref="System.InvalidProgramException"></exception>
        public EntityList QueryList(EntityQueryArgs args)
        {
            if (args.Query == null)
            {
                throw new ArgumentException("EntityQueryArgs.Query 属性不能为空。");
            }

            this.PrepareArgs(args);

            this.BuildDefaultQuerying(args);

            _dataProvider.OnQuerying(args);

            var entityList = args.EntityList;
            var oldCount   = entityList.Count;

            bool autoIndexEnabled = entityList.AutoTreeIndexEnabled;

            try
            {
                //在加载数据时,自动索引功能都不可用。
                entityList.AutoTreeIndexEnabled = false;

                QueryListCore(args, entityList);
            }
            finally
            {
                entityList.AutoTreeIndexEnabled = autoIndexEnabled;
            }

            this.EagerLoadOnCompleted(args, entityList, oldCount);

            return(entityList);
        }
Пример #2
0
        /// <summary>
        /// 所有使用 IQuery 的数据查询,在调用完应 queryBuilder 之后,都会执行此此方法。
        /// 所以子类可以重写此方法实现统一的查询条件逻辑。
        /// (例如,对于映射同一张表的几个子类的查询,可以使用此方法统一对所有方法都过滤)。
        ///
        /// 默认实现为:
        /// * 如果还没有进行排序,则进行默认的排序。
        /// * 如果单一参数实现了 IPagingCriteria 接口,则使用其中的分页信息进行分页。
        /// </summary>
        /// <param name="args"></param>
        internal protected virtual void OnQuerying(EntityQueryArgs args)
        {
            //如果没有指定 OrderNo 字段,则按照Id 排序。
            if (args.FetchType != FetchType.Count && !(args.Query as SqlSelect).HasOrdered())
            {
                args.Query.OrderBy.Add(
                    QueryFactory.Instance.OrderBy(args.Query.From.FindTable(Repo).Column(Entity.IdProperty))
                    );
            }

            //默认对分页进行处理。
            var pList = CurrentIEQC.Parameters;

            if (pList.Length == 1)
            {
                var userCriteria = pList[0] as ILoadOptionsCriteria;
                if (userCriteria != null)
                {
                    if (args.Filter == null)
                    {
                        args.PagingInfo = userCriteria.PagingInfo;
                    }
                    args.EagerLoadOptions = userCriteria.EagerLoad;
                }
            }
        }
Пример #3
0
        /// <summary>
        /// 通过 IQuery 对象来查询实体。
        /// </summary>
        /// <param name="query">查询对象。</param>
        /// <param name="paging">分页信息。</param>
        /// <param name="eagerLoad">需要贪婪加载的属性。</param>
        /// <param name="markTreeFullLoaded">如果某次查询结果是一棵完整的子树,那么必须设置此参数为 true ,才可以把整个树标记为完整加载。</param>
        /// <returns></returns>
        public EntityList QueryList(IQuery query, PagingInfo paging = null, EagerLoadOptions eagerLoad = null, bool markTreeFullLoaded = false)
        {
            var args = new EntityQueryArgs(query);

            args.MarkTreeFullLoaded = markTreeFullLoaded;
            args.SetDataLoadOptions(paging, eagerLoad);

            return(this.QueryList(args));
        }
Пример #4
0
        /// <summary>
        /// 所有使用 IQuery 的数据查询,在调用完应 queryBuilder 之后,都会执行此此方法。
        /// 所以子类可以重写此方法实现统一的查询条件逻辑。
        /// (例如,对于映射同一张表的几个子类的查询,可以使用此方法统一对所有方法都过滤)。
        ///
        /// 默认实现为:
        /// * 如果还没有进行排序,则进行默认的排序。
        /// * 如果单一参数实现了 IPagingCriteria 接口,则使用其中的分页信息进行分页。
        /// </summary>
        /// <param name="args"></param>
        internal protected virtual void OnQuerying(EntityQueryArgs args)
        {
            var h = Querying;

            if (h != null)
            {
                h(this, new QueryingEventArgs {
                    Args = args
                });
            }

            _dataQueryer.OnQuerying(args);
        }
Пример #5
0
        /// <summary>
        /// 通过 IQuery 对象从持久层中查询数据。
        /// 本方法只能由仓库中的方法来调用。本方法的返回值的类型将与仓库中方法的返回值保持一致。
        /// 支持的返回值:EntityList、Entity、int、LiteDataTable。
        /// </summary>
        /// <param name="query">查询对象。</param>
        /// <param name="paging">分页信息。</param>
        /// <param name="eagerLoad">需要贪婪加载的属性。</param>
        /// <param name="markTreeFullLoaded">如果某次查询结果是一棵完整的子树,那么必须设置此参数为 true ,才可以把整个树标记为完整加载。</param>
        /// <returns></returns>
        public object QueryData(IQuery query, PagingInfo paging = null, EagerLoadOptions eagerLoad = null, bool markTreeFullLoaded = false)
        {
            var queryType = FinalDataPortal.CurrentIEQC.QueryType;
            if (queryType == RepositoryQueryType.Table)
            {
                return this.QueryTable(query, paging);
            }

            var args = new EntityQueryArgs(query);
            args.MarkTreeFullLoaded = markTreeFullLoaded;
            args.SetDataLoadOptions(paging, eagerLoad);

            return this.QueryData(args);
        }
Пример #6
0
        private void BuildDefaultQuerying(EntityQueryArgs args)
        {
            var query = args.Query;

            //树型实体不支持修改排序规则!此逻辑不能放到 OnQueryBuilt 虚方法中,以免被重写。
            if (Repo.SupportTree)
            {
                //if (query.OrderBy.Count > 0)
                //{
                //    throw new InvalidOperationException(string.Format("树状实体 {0} 只不支持自定义排序,必须使用索引排序。", Repo.EntityType));
                //}
                var c = query.OrderBy.Count;
                if (c > 0)
                {
                    bool error = true;
                    //如果只有一个排序时,允许使用聚合父属性进行排序。
                    if (c == 1)
                    {
                        var parentProperty = _repository.FindParentPropertyInfo(false);
                        if (parentProperty != null)
                        {
                            var property  = query.OrderBy[0].Column.Property;
                            var pProperty = (parentProperty.ManagedProperty as IRefProperty).RefIdProperty;
                            error = property != pProperty;
                        }
                    }
                    if (error)
                    {
                        throw new InvalidOperationException(string.Format("树状实体 {0} 只不支持自定义排序,必须使用索引排序。", Repo.EntityType));
                    }
                }

                /*********************** 代码块解释 *********************************
                 * 以下,默认使用 TreeIndex 进行排序。
                 * 同时,在使用 TreeIndex 排序的基础上,还需要使用 Id 进行排序。
                 * TreeIndexHelper.ResetTreeIndex 在整理数据时,会把 TreeIndex 清空,此时数据可能无序。
                 * 而 Oracle 中查询时,返回的结果中 Id 可能是乱的,这会影响数据的加载。
                 **********************************************************************/
                var f     = QueryFactory.Instance;
                var table = query.From.FindTable(Repo);
                query.OrderBy.Add(
                    f.OrderBy(table.Column(Entity.TreeIndexProperty))
                    );
                query.OrderBy.Add(
                    f.OrderBy(table.IdColumn)
                    );
            }
        }
Пример #7
0
 /// <summary>
 /// 所有使用 IQuery 的数据查询,在调用完应 queryBuilder 之后,都会执行此此方法。
 /// 所以子类可以重写此方法实现统一的查询条件逻辑。
 /// (例如,对于映射同一张表的几个子类的查询,可以使用此方法统一对所有方法都过滤)。
 /// 
 /// 默认实现为:
 /// * 如果还没有进行排序,则进行默认的排序。
 /// * 如果单一参数实现了 IPagingCriteria 接口,则使用其中的分页信息进行分页。
 /// </summary>
 /// <param name="args"></param>
 protected internal virtual void OnQuerying(EntityQueryArgs args)
 {
     //默认对分页进行处理。
     var pList = FinalDataPortal.CurrentIEQC.Parameters;
     if (pList.Length == 1)
     {
         var userCriteria = pList[0] as ILoadOptionsCriteria;
         if (userCriteria != null)
         {
             if (args.Filter == null)
             {
                 args.PagingInfo = userCriteria.PagingInfo;
             }
             args.EagerLoadOptions = userCriteria.EagerLoad;
         }
     }
 }
Пример #8
0
        private void BuildDefaultQuerying(EntityQueryArgs args)
        {
            var query = args.Query;

            //树型实体不支持修改排序规则!此逻辑不能放到 OnQueryBuilt 虚方法中,以免被重写。
            if (Repo.SupportTree)
            {
                if (query.OrderBy.Count > 0)
                {
                    throw new InvalidOperationException(string.Format("树状实体 {0} 只不支持自定义排序,必须使用索引排序。", Repo.EntityType));
                }

                var f = QueryFactory.Instance;
                query.OrderBy.Add(
                    f.OrderBy(query.From.FindTable(Repo).Column(Entity.TreeIndexProperty))
                    );
            }
        }
Пример #9
0
        /// <summary>
        /// 通过托管属性查询条件来查询数据库,把满足条件的实体查询出来。
        /// </summary>
        /// <param name="args">托管属性查询条件。</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">args
        /// or
        /// args.PropertyQuery。</exception>
        /// <exception cref="System.NotSupportedException">使用内存过滤器的同时,不支持提供分页参数。</exception>
        protected EntityList QueryList(PropertyQueryArgs args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }
            if (args.PropertyQuery == null)
            {
                throw new ArgumentNullException("args.PropertyQuery。");
            }

            this.PrepareArgs(args);

            this.BuildDefaultQuerying(args);

            //this.OnPropertyQuerying(args);

            var dbQuery = args.PropertyQuery as PropertyQuery;

            IQuery query = this.ConvertToQuery(dbQuery);

            var entityArgs = new EntityQueryArgs
            {
                EntityList = args.EntityList,
                Filter     = args.Filter,
                MemoryList = args.MemoryList,
                PagingInfo = args.PropertyQuery.PagingInfo,
                Query      = query
            };

            entityArgs.SetFetchType(args.FetchType);
            if (dbQuery.EagerLoadProperties != null)
            {
                for (int i = 0, c = dbQuery.EagerLoadProperties.Count; i < c; i++)
                {
                    var item = dbQuery.EagerLoadProperties[i];
                    entityArgs.EagerLoad(item.Property as IProperty, item.Owner);
                }
            }

            return(base.QueryList(entityArgs));
        }
Пример #10
0
        private void BuildDefaultQuerying(EntityQueryArgs args)
        {
            var query = args.Query;

            //树型实体不支持修改排序规则!此逻辑不能放到 OnQueryBuilt 虚方法中,以免被重写。
            if (Repo.SupportTree)
            {
                //if (query.OrderBy.Count > 0)
                //{
                //    throw new InvalidOperationException(string.Format("树状实体 {0} 只不支持自定义排序,必须使用索引排序。", Repo.EntityType));
                //}
                var c = query.OrderBy.Count;
                if (c > 0)
                {
                    bool error = true;
                    //如果只有一个排序时,允许使用聚合父属性进行排序。
                    if (c == 1)
                    {
                        var parentProperty = _repository.FindParentPropertyInfo(false);
                        if (parentProperty != null)
                        {
                            var property  = query.OrderBy[0].Column.Property;
                            var pProperty = (parentProperty.ManagedProperty as IRefProperty).RefIdProperty;
                            error = property != pProperty;
                        }
                    }
                    if (error)
                    {
                        throw new InvalidOperationException(string.Format("树状实体 {0} 只不支持自定义排序,必须使用索引排序。", Repo.EntityType));
                    }
                }

                query.OrderBy.Add(
                    QueryFactory.Instance.OrderBy(query.From.FindTable(Repo).Column(Entity.TreeIndexProperty))
                    );
            }
        }
Пример #11
0
 /// <summary>
 /// 通过 IQuery 对象从持久层中查询数据。
 /// 本方法只能由仓库中的方法来调用。本方法的返回值的类型将与仓库中方法的返回值保持一致。
 /// 支持的返回值:EntityList、Entity、int。
 /// </summary>
 /// <param name="args">The arguments.</param>
 /// <returns></returns>
 protected object QueryData(EntityQueryArgs args)
 {
     return(this.DataQueryer.QueryData(args));
 }
Пример #12
0
 /// <summary>
 /// 所有使用 IQuery 的数据查询,在调用完应 queryBuilder 之后,都会执行此此方法。
 /// 所以子类可以重写此方法实现统一的查询条件逻辑。
 /// (例如,对于映射同一张表的几个子类的查询,可以使用此方法统一对所有方法都过滤)。
 /// 
 /// 默认实现为:
 /// * 如果还没有进行排序,则进行默认的排序。
 /// * 如果单一参数实现了 IPagingCriteria 接口,则使用其中的分页信息进行分页。
 /// </summary>
 /// <param name="args"></param>
 protected internal virtual void OnQuerying(EntityQueryArgs args)
 {
     _dataQueryer.OnQuerying(args);
 }
Пример #13
0
 /// <summary>
 /// 子类重写此方法,查询从持久层加载列表的具体实现。
 /// </summary>
 /// <param name="args">The arguments.</param>
 /// <param name="entityList">The entity list.</param>
 protected abstract void QueryListCore(EntityQueryArgs args, EntityList entityList);
Пример #14
0
 EntityList IRepositoryDataQueryAPI.QueryList(EntityQueryArgs args)
 {
     return(this.QueryList(args));
 }
Пример #15
0
        /// <summary>
        /// 通过 IQuery 对象来查询实体。
        /// </summary>
        /// <param name="args">The arguments.</param>
        /// <returns></returns>
        /// <exception cref="System.NotSupportedException">使用内存过滤器的同时,不支持提供分页参数。</exception>
        /// <exception cref="System.InvalidProgramException"></exception>
        protected EntityList QueryList(EntityQueryArgs args)
        {
            if (args.Query == null)
            {
                throw new ArgumentException("EntityQueryArgs.Query 属性不能为空。");
            }

            this.PrepareArgs(args);

            this.BuildDefaultQuerying(args);

            this.OnQuerying(args);

            var entityList = args.EntityList;
            var oldCount   = entityList.Count;

            bool autoIndexEnabled = entityList.AutoTreeIndexEnabled;

            try
            {
                //在加载数据时,自动索引功能都不可用。
                entityList.AutoTreeIndexEnabled = false;

                using (var dba = Repo.RdbDataProvider.CreateDbAccesser())
                {
                    //以下代码,开始访问数据库查询数据。
                    var dbTable = Repo.RdbDataProvider.DbTable;
                    if (args.Filter != null)
                    {
                        #region 内存过滤式加载

                        if (!PagingInfo.IsNullOrEmpty(args.PagingInfo))
                        {
                            throw new NotSupportedException("使用内存过滤器的同时,不支持提供分页参数。");
                        }

                        args.MemoryList = new List <Entity>();
                        dbTable.QueryList(dba, args);
                        this.LoadByFilter(args);

                        #endregion
                    }
                    else
                    {
                        if (args.FetchType == FetchType.Count)
                        {
                            #region 查询 Count

                            var count = dbTable.Count(dba, args.Query);
                            entityList.SetTotalCount(count);

                            #endregion
                        }
                        else
                        {
                            //是否需要为 PagingInfo 设置统计值。
                            var pi = args.PagingInfo;
                            var pagingInfoCount = !PagingInfo.IsNullOrEmpty(pi) && pi.IsNeedCount;

                            //如果 pagingInfoCount 为真,则在访问数据库时,会设置好 PagingInfo 的总行数。
                            dbTable.QueryList(dba, args);

                            //最后,还需要设置列表的 TotalCount。
                            if (pagingInfoCount)
                            {
                                entityList.SetTotalCount(pi.TotalCount);
                            }
                        }
                    }
                }
            }
            finally
            {
                entityList.AutoTreeIndexEnabled = autoIndexEnabled;
            }

            this.EagerLoadOnCompleted(args, entityList, oldCount);

            return(entityList);
        }
Пример #16
0
 /// <summary>
 /// 通过 IQuery 对象来查询实体。
 /// </summary>
 /// <param name="args">The arguments.</param>
 /// <returns></returns>
 /// <exception cref="System.NotSupportedException">使用内存过滤器的同时,不支持提供分页参数。</exception>
 /// <exception cref="System.InvalidProgramException"></exception>
 protected EntityList QueryList(EntityQueryArgs args)
 {
     return(this.DataQueryer.QueryList(args));
 }
Пример #17
0
        /// <summary>
        /// 通过托管属性查询条件来查询数据库,把满足条件的实体查询出来。
        /// </summary>
        /// <param name="args">托管属性查询条件。</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">args
        /// or
        /// args.PropertyQuery。</exception>
        /// <exception cref="System.NotSupportedException">使用内存过滤器的同时,不支持提供分页参数。</exception>
        protected EntityList QueryList(PropertyQueryArgs args)
        {
            if (args == null) throw new ArgumentNullException("args");
            if (args.PropertyQuery == null) throw new ArgumentNullException("args.PropertyQuery。");

            this.PrepareArgs(args);

            this.BuildDefaultQuerying(args);

            //this.OnPropertyQuerying(args);

            var dbQuery = args.PropertyQuery as PropertyQuery;

            IQuery query = this.ConvertToQuery(dbQuery);

            var entityArgs = new EntityQueryArgs
            {
                EntityList = args.EntityList,
                Filter = args.Filter,
                MemoryList = args.MemoryList,
                PagingInfo = args.PropertyQuery.PagingInfo,
                Query = query
            };
            entityArgs.SetFetchType(args.FetchType);
            if (dbQuery.EagerLoadProperties != null)
            {
                for (int i = 0, c = dbQuery.EagerLoadProperties.Count; i < c; i++)
                {
                    var item = dbQuery.EagerLoadProperties[i];
                    entityArgs.EagerLoad(item.Property as IProperty, item.Owner);
                }
            }

            return base.QueryList(entityArgs);
        }
Пример #18
0
 /// <summary>
 /// 所有使用 IQuery 的数据查询,在调用完应 queryBuilder 之后,都会执行此此方法。
 /// 所以子类可以重写此方法实现统一的查询条件逻辑。
 /// (例如,对于映射同一张表的几个子类的查询,可以使用此方法统一对所有方法都过滤)。
 ///
 /// 默认实现为:
 /// * 如果还没有进行排序,则进行默认的排序。
 /// * 如果单一参数实现了 IPagingCriteria 接口,则使用其中的分页信息进行分页。
 /// </summary>
 /// <param name="args"></param>
 internal protected virtual void OnQuerying(EntityQueryArgs args)
 {
     _dataQueryer.OnQuerying(args);
 }