1. 程式人生 > >應用程式框架實戰二十六:查詢物件

應用程式框架實戰二十六:查詢物件

using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using Util.Datas.Queries.Criterias; using Util.Datas.Queries.OrderBys; using Util.Domains; using Util.Domains.Repositories; namespace Util.Datas.Queries { /// <summary> /// 查詢物件
/// </summary> /// <typeparam name="TEntity">實體型別</typeparam> /// <typeparam name="TKey">實體標識型別</typeparam> public class Query<TEntity, TKey> : Pager, IQuery<TEntity, TKey> where TEntity : class ,IAggregateRoot<TKey> { #region 構造方法 ///
<summary> /// 初始化查詢物件 /// </summary> public Query() { OrderBuilder = new OrderByBuilder(); } /// <summary> /// 初始化查詢物件 /// </summary> /// <param name="pager">分頁物件</param> public Query( IPager pager ) : this
() { Page = pager.Page; PageSize = pager.PageSize; TotalCount = pager.TotalCount; OrderBy( pager.Order ); } #endregion #region 屬性 /// <summary> /// 查詢條件 /// </summary> private ICriteria<TEntity> Criteria { get; set; } /// <summary> /// 排序生成器 /// </summary> private OrderByBuilder OrderBuilder { get; set; } #endregion #region GetPredicate(獲取謂詞) /// <summary> /// 獲取謂詞 /// </summary> public Expression<Func<TEntity, bool>> GetPredicate() { if ( Criteria == null ) return null; return Criteria.GetPredicate(); } #endregion #region GetOrderBy(獲取排序) /// <summary> /// 獲取排序 /// </summary> public string GetOrderBy() { Order = OrderBuilder.Generate(); if ( string.IsNullOrWhiteSpace( Order ) ) Order = "Id desc"; return Order; } #endregion #region 過濾條件 /// <summary> /// 新增謂詞,僅能新增一個條件,如果引數值為空,則忽略該條件 /// </summary> /// <param name="predicate">謂詞</param> /// <param name="isOr">是否使用Or連線</param> public IQuery<TEntity, TKey> Filter( Expression<Func<TEntity, bool>> predicate,bool isOr = false ) { predicate = QueryHelper.ValidatePredicate( predicate ); if ( predicate == null ) return this; if ( isOr ) Or( predicate ); else And( predicate ); return this; } /// <summary> /// 過濾條件 /// </summary> /// <param name="propertyName">屬性名</param> /// <param name="value"></param> /// <param name="operator">運算子</param> public IQuery<TEntity, TKey> Filter( string propertyName, object value, Operator @operator = Operator.Equal ) { return Filter( Lambda.ParsePredicate<TEntity>( propertyName, value, @operator ) ); } /// <summary> /// 新增查詢條件 /// </summary> /// <param name="criteria">查詢條件</param> public IQuery<TEntity, TKey> Filter( ICriteria<TEntity> criteria ) { And( criteria.GetPredicate() ); return this; } /// <summary> /// 過濾int數值段 /// </summary> /// <typeparam name="TProperty">屬性型別</typeparam> /// <param name="propertyExpression">屬性表示式,範例:t => t.Age</param> /// <param name="min">最小值</param> /// <param name="max">最大值</param> public IQuery<TEntity, TKey> FilterInt<TProperty>( Expression<Func<TEntity, TProperty>> propertyExpression, int? min, int? max ) { return Filter( new IntSegmentCriteria<TEntity, TProperty>( propertyExpression, min, max ) ); } /// <summary> /// 過濾double數值段 /// </summary> /// <typeparam name="TProperty">屬性型別</typeparam> /// <param name="propertyExpression">屬性表示式,範例:t => t.Age</param> /// <param name="min">最小值</param> /// <param name="max">最大值</param> public IQuery<TEntity, TKey> FilterDouble<TProperty>( Expression<Func<TEntity, TProperty>> propertyExpression, double? min, double? max ) { return Filter( new DoubleSegmentCriteria<TEntity, TProperty>( propertyExpression, min, max ) ); } /// <summary> /// 過濾日期段,不包含時間 /// </summary> /// <typeparam name="TProperty">屬性型別</typeparam> /// <param name="propertyExpression">屬性表示式,範例:t => t.Age</param> /// <param name="min">最小值</param> /// <param name="max">最大值</param> public IQuery<TEntity, TKey> FilterDate<TProperty>( Expression<Func<TEntity, TProperty>> propertyExpression, DateTime? min, DateTime? max ) { return Filter( new DateSegmentCriteria<TEntity, TProperty>( propertyExpression, min, max ) ); } /// <summary> /// 過濾日期時間段,包含時間 /// </summary> /// <typeparam name="TProperty">屬性型別</typeparam> /// <param name="propertyExpression">屬性表示式,範例:t => t.Age</param> /// <param name="min">最小值</param> /// <param name="max">最大值</param> public IQuery<TEntity, TKey> FilterDateTime<TProperty>( Expression<Func<TEntity, TProperty>> propertyExpression, DateTime? min, DateTime? max ) { return Filter( new DateTimeSegmentCriteria<TEntity, TProperty>( propertyExpression, min, max ) ); } /// <summary> /// 過濾decimal數值段 /// </summary> /// <typeparam name="TProperty">屬性型別</typeparam> /// <param name="propertyExpression">屬性表示式,範例:t => t.Age</param> /// <param name="min">最小值</param> /// <param name="max">最大值</param> public IQuery<TEntity, TKey> FilterDecimal<TProperty>( Expression<Func<TEntity, TProperty>> propertyExpression, decimal? min, decimal? max ) { return Filter( new DecimalSegmentCriteria<TEntity, TProperty>( propertyExpression, min, max ) ); } #endregion #region 連線 /// <summary> /// 與連線,將傳入的查詢條件合併到當前物件 /// </summary> /// <param name="query">查詢物件</param> public IQuery<TEntity, TKey> And( IQuery<TEntity, TKey> query ) { return And( query.GetPredicate() ); } /// <summary> /// 與連線,將傳入的查詢條件合併到當前物件 /// </summary> /// <param name="predicate">謂詞</param> public IQuery<TEntity, TKey> And( Expression<Func<TEntity, bool>> predicate ) { if ( Criteria == null ) { Criteria = new Criteria<TEntity>( predicate ); return this; } Criteria = new AndCriteria<TEntity>( Criteria.GetPredicate(), predicate ); return this; } /// <summary> /// 或連線,將傳入的查詢條件合併到當前物件 /// </summary> /// <param name="query">查詢物件</param> public IQuery<TEntity, TKey> Or( IQuery<TEntity, TKey> query ) { return Or( query.GetPredicate() ); } /// <summary> /// 或連線,將傳入的查詢條件合併到當前物件 /// </summary> /// <param name="predicate">謂詞</param> public IQuery<TEntity, TKey> Or( Expression<Func<TEntity, bool>> predicate ) { if ( Criteria == null ) { Criteria = new Criteria<TEntity>( predicate ); return this; } Criteria = new OrCriteria<TEntity>( Criteria.GetPredicate(), predicate ); return this; } #endregion #region OrderBy(排序) /// <summary> /// 新增排序,支援多次呼叫OrderBy建立多級排序 /// </summary> /// <typeparam name="TProperty">屬性型別</typeparam> /// <param name="expression">屬性表示式</param> /// <param name="desc">是否降序</param> public IQuery<TEntity, TKey> OrderBy<TProperty>( Expression<Func<TEntity, TProperty>> expression, bool desc = false ) { return OrderBy( Lambda.GetName( expression ), desc ); } /// <summary> /// 新增排序,支援多次呼叫OrderBy建立多級排序 /// </summary> /// <param name="propertyName">排序屬性</param> /// <param name="desc">是否降序</param> public IQuery<TEntity, TKey> OrderBy( string propertyName, bool desc = false ) { OrderBuilder.Add( propertyName, desc ); GetOrderBy(); return this; } #endregion #region Clear(清理) /// <summary> /// 清理 /// </summary> public void Clear() { Criteria = null; OrderBuilder = new OrderByBuilder(); } #endregion #region GetList(獲取列表) /// <summary> /// 獲取列表 /// </summary> /// <param name="queryable">資料來源</param> public List<TEntity> GetList( IQueryable<TEntity> queryable ) { return Execute( queryable ).OrderBy( Order ).ToList(); } /// <summary> /// 執行過濾和分頁 /// </summary> private IQueryable<TEntity> Execute( IQueryable<TEntity> queryable ) { queryable.CheckNull( "queryable" ); queryable = FilterBy( queryable ); GetOrderBy(); return queryable; } /// <summary> /// 過濾 /// </summary> private IQueryable<TEntity> FilterBy( IQueryable<TEntity> queryable ) { if ( Criteria == null ) return queryable; return queryable.Where( Criteria.GetPredicate() ); } #endregion #region GetPagerList(獲取分頁列表) /// <summary> /// 獲取分頁列表 /// </summary> /// <param name="queryable">資料來源</param> public PagerList<TEntity> GetPagerList( IQueryable<TEntity> queryable ) { return Execute( queryable ).PagerResult( this ); } #endregion } }