ABP開發(fā)框架前后端開發(fā)系列---(13)高級查詢功能及界面的處理

在一般的檢索界面中助币,基于界面易用和美觀方便的考慮朦蕴,我們往往只提供一些常用的條件查詢進行列表數(shù)據(jù)的查詢疏尿,但是有時候一些業(yè)務(wù)表字段很多榆鼠,一些不常見的條件可能在某些場景下也需要用到。因此我們在通用的查詢條件之外俱笛,一般可以考慮增加 一個高級查詢的模塊來管理這些不常見條件的查詢處理捆姜。本篇隨筆基于這個需求,綜合ABP框架的特點迎膜,整合了高級查詢模塊功能的處理泥技。

1、高級查詢模塊的回顧

我們知道磕仅,在界面布局中珊豹,一般常見的查詢條件不能太多,否則會顯得臃腫而且占用太多空間宽涌,非常不美觀平夜,因此常見的查詢都是提供寥寥幾個的輸出條件進行列表記錄的查詢的。

image

又或者一些更多內(nèi)容的界面卸亮,我們也是僅僅提供多幾個條件忽妒,其他的想辦法通過高級查詢界面進行查詢管理。

image

在早期博客里面《Winform開發(fā)框架之通用高級查詢模塊》兼贸,我曾經(jīng)介紹過一款通用的高級查詢界面處理段直,用在Winform框架里面,可以對數(shù)據(jù)表更多的字段進行統(tǒng)一的查詢處理溶诞。

對于內(nèi)容較多的查詢鸯檬,我們可以在主界面增加一個高級查詢按鈕入口,如上圖所示螺垢,單擊后喧务,顯示一個所有字段的列表,如下界面枉圃。

image

一般來說功茴,查詢條件分為文本輸入,如姓名孽亲,郵件坎穿,名稱等這些。

image

日期類型條件輸入界面:

image

數(shù)字類型條件輸入界面:

image

輸入以上幾種條件后,高級查詢界面里面會顯示友好的條件內(nèi)容玲昧,確保用戶能夠看懂輸入的條件栖茉,如下所示是輸入幾個不同類型的條件的顯示內(nèi)容。

image

以上是高級查詢模塊的思路孵延,整體界面和處理邏輯雖然可以采用吕漂,但是在ABP框架模式下,以前的處理方式有所不同了隙袁,下面詳細介紹一下如何在ABP框架模塊下整合這個高級查詢模塊的內(nèi)容痰娱。

2弃榨、ABP框架模塊下的高級查詢處理

我們先來了解一下最終在ABP框架下整合的高級查詢模塊界面如下所示菩收。

image

可以設(shè)置一些模糊查詢條件,以及一些區(qū)間的查詢值鲸睛,如下所示娜饵。

image

這個模塊是以ABP框架的Web API獲取數(shù)據(jù),并通過Winform界面進行調(diào)用官辈,從而形成了一個ABP+Winform的框架體系箱舞。

前面ABP框架系列介紹過,我們一般使用GetAll和分頁條件DTO進行數(shù)據(jù)的檢索拳亿,如下是產(chǎn)品分頁DTO的定義

    /// <summary>
    /// 用于根據(jù)條件分頁查詢晴股,DTO對象
    /// </summary>
    public class ProductPagedDto : PagedAndSortedInputDto

而PagedAndSortedInputDto也是自定義的類,它主要用來承載一些分頁和排序的信息肺魁,如下所示

    /// <summary>
    /// 帶有排序?qū)ο蟮姆猪摶?    /// </summary>
    public class PagedAndSortedInputDto : PagedInputDto, ISortedResultRequest
    {
        /// <summary>
        /// 排序信息
        /// </summary>
        public string Sorting { get; set; }

其中的PagedInputDto也是自定義類电湘,主要承載分頁信息。

    /// <summary>
    /// 分頁對象
    /// </summary>
    public class PagedInputDto : IPagedResultRequest
    {
        [Range(1, int.MaxValue)]
        public int MaxResultCount { get; set; }

        [Range(0, int.MaxValue)]
        public int SkipCount { get; set; }

        public PagedInputDto()
        {
            MaxResultCount = int.MaxValue;
        }
    }

這樣的構(gòu)建鹅经,我們可以傳遞分頁和排序信息寂呛,因此在GetAll函數(shù)里面,就可以根據(jù)這些條件進行數(shù)據(jù)查詢了瘾晃。

而我們通過重寫過濾條件和排序處理贷痪,就可以實現(xiàn)數(shù)據(jù)的分頁查詢了。對于產(chǎn)品信息的過濾處理和排序處理蹦误,我們重寫函數(shù)如下所示劫拢。

        /// <summary>
        /// 自定義條件處理
        /// </summary>
        /// <param name="input">查詢條件Dto</param>
        /// <returns></returns>
        protected override IQueryable<Product> CreateFilteredQuery(ProductPagedDto input)
        {
            return base.CreateFilteredQuery(input)
                .WhereIf(!input.ExcludeId.IsNullOrWhiteSpace(), t => t.Id != input.ExcludeId) //不包含排除ID

                .WhereIf(!input.ProductNo.IsNullOrWhiteSpace(), t => t.ProductNo.Contains(input.ProductNo)) //如需要精確匹配則用Equals
                .WhereIf(!input.BarCode.IsNullOrWhiteSpace(), t => t.BarCode.Contains(input.BarCode)) //如需要精確匹配則用Equals
                .WhereIf(!input.MaterialCode.IsNullOrWhiteSpace(), t => t.MaterialCode.Contains(input.MaterialCode)) //如需要精確匹配則用Equals
                .WhereIf(!input.ProductType.IsNullOrWhiteSpace(), t => t.ProductType.Contains(input.ProductType)) //如需要精確匹配則用Equals
                .WhereIf(!input.ProductName.IsNullOrWhiteSpace(), t => t.ProductName.Contains(input.ProductName)) //如需要精確匹配則用Equals
                .WhereIf(!input.Unit.IsNullOrWhiteSpace(), t => t.Unit.Contains(input.Unit)) //如需要精確匹配則用Equals
                .WhereIf(!input.Note.IsNullOrWhiteSpace(), t => t.Note.Contains(input.Note)) //如需要精確匹配則用Equals
                .WhereIf(!input.Description.IsNullOrWhiteSpace(), t => t.Description.Contains(input.Description)) //如需要精確匹配則用Equals
                 
                 //狀態(tài)
                .WhereIf(input.Status.HasValue, t => t.Status==input.Status)
                                                                                              
                 //成本價區(qū)間查詢
                .WhereIf(input.PriceStart.HasValue, s => s.Price >= input.PriceStart.Value)
                .WhereIf(input.PriceEnd.HasValue, s => s.Price <= input.PriceEnd.Value)

                //銷售價區(qū)間查詢
                .WhereIf(input.SalePriceStart.HasValue, s => s.SalePrice >= input.SalePriceStart.Value)
                .WhereIf(input.SalePriceEnd.HasValue, s => s.SalePrice <= input.SalePriceEnd.Value)

                //特價區(qū)間查詢
                .WhereIf(input.SpecialPriceStart.HasValue, s => s.SpecialPrice >= input.SpecialPriceStart.Value)
                .WhereIf(input.SpecialPriceEnd.HasValue, s => s.SpecialPrice <= input.SpecialPriceEnd.Value)
                .WhereIf(input.IsUseSpecial.HasValue, t => t.IsUseSpecial == input.IsUseSpecial) //如需要精確匹配則用Equals
                                                                                                  
                //最低折扣區(qū)間查詢
                .WhereIf(input.LowestDiscountStart.HasValue, s => s.LowestDiscount >= input.LowestDiscountStart.Value)
                .WhereIf(input.LowestDiscountEnd.HasValue, s => s.LowestDiscount <= input.LowestDiscountEnd.Value)

                //創(chuàng)建日期區(qū)間查詢
                .WhereIf(input.CreationTimeStart.HasValue, s => s.CreationTime >= input.CreationTimeStart.Value)
                .WhereIf(input.CreationTimeEnd.HasValue, s => s.CreationTime <= input.CreationTimeEnd.Value);
        }

        /// <summary>
        /// 自定義排序處理
        /// </summary>
        /// <param name="query">可查詢LINQ</param>
        /// <param name="input">查詢條件Dto</param>
        /// <returns></returns>
        protected override IQueryable<Product> ApplySorting(IQueryable<Product> query, ProductPagedDto input)
        {
            //按創(chuàng)建時間倒序排序
            return base.ApplySorting(query, input).OrderByDescending(s => s.CreationTime);//時間降序
        }

雖然我們一般在界面上不會放置所有的條件,但是高級查詢模塊倒是可以把分頁條件DTO里面的條件全部擺上去的强胰。

image

高級查詢模塊的條件如下所示舱沧。

image

我們高級查詢里面的條件還是以GetAll里面的對象分頁查詢Dto里面的屬性,我們需要根據(jù)這些條件進行構(gòu)建哪廓,也需要以這些屬性的類型進行一個控件的選擇狗唉。

因此我們需要一個屬性的名稱說明,以及在高級查詢模塊的列表界面中對顯示那些字段進行控制涡真,如下代碼所示分俯。

        private FrmAdvanceSearch dlg;
        /// <summary>
        /// 高級查詢的操作
        /// </summary>        
        private async void AdvanceSearch()
        {
            if (dlg == null)
            {
                dlg = new FrmAdvanceSearch();
                dlg.SetFieldTypeList<ProductPagedDto>();//通過分頁對象獲取查詢屬性和類型 
                dlg.ColumnNameAlias = await ProductApiCaller.Instance.GetColumnNameAlias();                
                dlg.DisplayColumns = "ProductNo,BarCode,MaterialCode,ProductType,ProductName,Unit,Price,SalePrice,SpecialPrice,IsUseSpecial,LowestDiscount,Note,Description,Status,CreatorUserId,CreationTime";

通過 SetFieldTypeList<ProductPagedDto> 的處理肾筐,我們把分頁對象的查詢屬性和類型賦值給了高級查詢模塊,讓它根據(jù)類型來創(chuàng)建不同的輸入顯示缸剪,如常規(guī)的字符串吗铐、數(shù)值區(qū)段、日期區(qū)段杏节,下拉列表等等唬渗。

對于下拉列表,我們需要綁定它的數(shù)據(jù)源奋渔,如下代碼所示镊逝。

 dlg.AddColumnListItem("ProductType", await DictItemUtil.GetDictListItemByDictType("產(chǎn)品類型"));//字典列表
 dlg.AddColumnListItem("Status", await DictItemUtil.GetDictListItemByDictType("產(chǎn)品狀態(tài)"));//字典列表

而對于一些常規(guī)的固定列表,也可以以類似的方式加入下拉列表

    //固定轉(zhuǎn)義的列表
    var specialList = new List<CListItem>() { new CListItem("特價", "True"), new CListItem("一般", "False") };
    dlg.AddColumnListItem("IsUseSpecial", specialList);

或者

    dlg.AddColumnListItem("Sex", "男,女");//固定列表

因此整個調(diào)用高級查詢模塊的代碼如下所示

    private FrmAdvanceSearch dlg;
    /// <summary>
    /// 高級查詢的操作
    /// </summary>        
    private async void AdvanceSearch()
    {
        if (dlg == null)
        {
            dlg = new FrmAdvanceSearch();
            dlg.SetFieldTypeList<ProductPagedDto>();//通過分頁對象獲取查詢屬性和類型 
            dlg.ColumnNameAlias = await ProductApiCaller.Instance.GetColumnNameAlias();                
            dlg.DisplayColumns = "ProductNo,BarCode,MaterialCode,ProductType,ProductName,Unit,Price,SalePrice,SpecialPrice,IsUseSpecial,LowestDiscount,Note,Description,Status,CreatorUserId,CreationTime";

            #region 下拉列表數(shù)據(jù)

            dlg.AddColumnListItem("ProductType", await DictItemUtil.GetDictListItemByDictType("產(chǎn)品類型"));//字典列表
            dlg.AddColumnListItem("Status", await DictItemUtil.GetDictListItemByDictType("產(chǎn)品狀態(tài)"));//字典列表

            //固定轉(zhuǎn)義的列表
            var specialList = new List<CListItem>() { new CListItem("特價", "True"), new CListItem("一般", "False") };
            dlg.AddColumnListItem("IsUseSpecial", specialList);

            //dlg.AddColumnListItem("Sex", "男,女");//固定列表
            //dlg.AddColumnListItem("Credit", await ProductApiCaller.Instance.GetFieldList("Credit"));//動態(tài)列表

            #endregion

            dlg.ConditionChanged += new FrmAdvanceSearch.ConditionChangedEventHandler(dlg_ConditionChanged);
        }
        dlg.ShowDialog();
    }

在處理獲取數(shù)據(jù)GetData函數(shù)的時候嫉鲸,我們需要根據(jù)高級查詢進行一定的切換撑蒜,以便顯示正確的過濾條件,如下代碼所示是獲取數(shù)據(jù)的處理玄渗。

        /// <summary>
        /// 獲取數(shù)據(jù)
        /// </summary>
        /// <returns></returns>
        private async Task<IPagedResult<ProductDto>> GetData()
        {
            ProductPagedDto pagerDto = null;
            if (advanceCondition != null)
            {
                pagerDto = new ProductPagedDto(this.winGridViewPager1.PagerInfo);
                pagerDto = dlg.GetPagedResult(pagerDto);               
            }
            else
            {
                //構(gòu)建分頁的條件和查詢條件
                pagerDto = new ProductPagedDto(this.winGridViewPager1.PagerInfo)
                {
                    //添加所需條件
                    ProductNo = this.txtProductNo.Text.Trim(),
                    BarCode = this.txtBarCode.Text.Trim(),
                    MaterialCode = this.txtMaterialCode.Text.Trim(),
                    ProductType = this.txtProductType.Text.Trim(),
                    ProductName = this.txtProductName.Text.Trim(),
                    Description = this.txtDescription.Text.Trim(),
                };

                //日期和數(shù)值范圍定義
                //創(chuàng)建時間座菠,需在ProductPagedDto中添加DateTime?類型字段CreationTimeStart和CreationTimeEnd
                var CreationTime = new TimeRange(this.txtCreationTime1.Text, this.txtCreationTime2.Text); //日期類型
                pagerDto.CreationTimeStart = CreationTime.Start;
                pagerDto.CreationTimeEnd = CreationTime.End;

            }

            var result = await ProductApiCaller.Instance.GetAll(pagerDto);
            return result;
        }

在高級查詢的處理方式下,我們是傳入一個列表的分頁對象屬性藤树,然后傳入一個分頁DTO對象浴滴,就可以構(gòu)建出我們需要的分頁查詢條件,傳遞給Web API端獲取對應(yīng)條件的數(shù)據(jù)了岁钓。

    pagerDto = new ProductPagedDto(this.winGridViewPager1.PagerInfo);
    pagerDto = dlg.GetPagedResult(pagerDto);        

而高級查詢模塊升略,所需要處理的邏輯就是需要根據(jù)不同的屬性類型,賦值常規(guī)的屬性值或者區(qū)段屬性值甜紫,從而構(gòu)建出分頁對應(yīng)的屬性條件即可降宅。

如果是區(qū)段(包括日期或者數(shù)值)的,我們分頁查詢條件里面囚霸,會有一個ABCStart,ABCEnd的對象屬性腰根,依照這個規(guī)則,獲取到對應(yīng)的用戶輸入拓型,采用反射方式賦值DTO對象即可额嘿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市劣挫,隨后出現(xiàn)的幾起案子册养,更是在濱河造成了極大的恐慌,老刑警劉巖压固,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件球拦,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機坎炼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門愧膀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谣光,你說我怎么就攤上這事檩淋。” “怎么了萄金?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵蟀悦,是天一觀的道長。 經(jīng)常有香客問我氧敢,道長日戈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任福稳,我火速辦了婚禮涎拉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘的圆。我一直安慰自己,他們只是感情好半火,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布越妈。 她就那樣靜靜地躺著,像睡著了一般钮糖。 火紅的嫁衣襯著肌膚如雪梅掠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天店归,我揣著相機與錄音阎抒,去河邊找鬼。 笑死消痛,一個胖子當(dāng)著我的面吹牛且叁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秩伞,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼逞带,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了纱新?” 一聲冷哼從身側(cè)響起展氓,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎脸爱,沒想到半個月后遇汞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年空入,在試婚紗的時候發(fā)現(xiàn)自己被綠了教寂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡执庐,死狀恐怖酪耕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情轨淌,我是刑警寧澤迂烁,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站递鹉,受9級特大地震影響盟步,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜躏结,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一却盘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧媳拴,春花似錦黄橘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至子巾,卻和暖如春帆赢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背线梗。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工椰于, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仪搔。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓瘾婿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親僻造。 傳聞我的和親對象是個殘疾皇子憋他,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容