/// <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); }
/// <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; } } }
/// <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)); }
/// <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); }
/// <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); }
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) ); } }
/// <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; } } }
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)) ); } }
/// <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)); }
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)) ); } }
/// <summary> /// 通过 IQuery 对象从持久层中查询数据。 /// 本方法只能由仓库中的方法来调用。本方法的返回值的类型将与仓库中方法的返回值保持一致。 /// 支持的返回值:EntityList、Entity、int。 /// </summary> /// <param name="args">The arguments.</param> /// <returns></returns> protected object QueryData(EntityQueryArgs args) { return(this.DataQueryer.QueryData(args)); }
/// <summary> /// 所有使用 IQuery 的数据查询,在调用完应 queryBuilder 之后,都会执行此此方法。 /// 所以子类可以重写此方法实现统一的查询条件逻辑。 /// (例如,对于映射同一张表的几个子类的查询,可以使用此方法统一对所有方法都过滤)。 /// /// 默认实现为: /// * 如果还没有进行排序,则进行默认的排序。 /// * 如果单一参数实现了 IPagingCriteria 接口,则使用其中的分页信息进行分页。 /// </summary> /// <param name="args"></param> protected internal virtual void OnQuerying(EntityQueryArgs args) { _dataQueryer.OnQuerying(args); }
/// <summary> /// 子类重写此方法,查询从持久层加载列表的具体实现。 /// </summary> /// <param name="args">The arguments.</param> /// <param name="entityList">The entity list.</param> protected abstract void QueryListCore(EntityQueryArgs args, EntityList entityList);
EntityList IRepositoryDataQueryAPI.QueryList(EntityQueryArgs args) { return(this.QueryList(args)); }
/// <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); }
/// <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)); }
/// <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); }
/// <summary> /// 所有使用 IQuery 的数据查询,在调用完应 queryBuilder 之后,都会执行此此方法。 /// 所以子类可以重写此方法实现统一的查询条件逻辑。 /// (例如,对于映射同一张表的几个子类的查询,可以使用此方法统一对所有方法都过滤)。 /// /// 默认实现为: /// * 如果还没有进行排序,则进行默认的排序。 /// * 如果单一参数实现了 IPagingCriteria 接口,则使用其中的分页信息进行分页。 /// </summary> /// <param name="args"></param> internal protected virtual void OnQuerying(EntityQueryArgs args) { _dataQueryer.OnQuerying(args); }