ABP開發框架前后端開發系列---(6)ABP基礎接口處理和省份城市行政區管理模塊的開發

最近沒有更新ABP框架的相關文章,一直在研究和封裝相關的接口,總算告一段落,開始繼續整理下開發心得。上次我在隨筆《ABP開發框架前后端開發系列---(5)Web API調用類在Winform項目中的使用》中介紹了字典模塊的管理,以及實現了常規的獲取所有記錄,獲取條件查詢記錄,創建、更新、刪除這些接口。本篇繼續深入介紹ABP框架在實際項目中使用的情況,本篇隨筆整理對ABP基礎接口,以及展示完成的省份城市行政區管理模塊的內容。

1、ABP常規處理接口

根據ABP框架默認提供的一些接口,我們可以在服務端封裝好相關的Web API接口(由于動態API的便利,其實是完成ApplicationService層即可),前面介紹了獲取條件查詢記錄,創建、更新、刪除這些接口的實現和處理,以及可以擴展自己的自定義業務接口,如下是字典模塊的接口關系。

image

字典管理界面,列出字典類型,并對字典類型下的字典數據進行分頁展示,分頁展示利用分頁控件展示。

image

新增或者編輯窗體界面如下

image

或者是批量的字典數據錄入

image

這個精確或者模糊查詢,則是在應用服務層里面定義規則的,在應用服務層接口類里面,重寫CreateFilteredQuery可以設置GetAll的查詢規則,重寫ApplySorting則可以指定列表的排序順序。

image

2、ABP常規查詢接口的細化

在前面介紹了的內容匯總,基本上實現了常規數據的分頁查詢,我們可以看到,對于字典數據來說,分頁查詢條件是在DictDataPagedDto里面定義,這個是我們定義的分頁條件,如下代碼所示。

    /// <summary>
    /// 用于根據條件分頁查詢
    /// </summary>
    public class DictDataPagedDto : PagedResultRequestDto
    {
        /// <summary>
        /// 字典類型ID
        /// </summary>
        public virtual string DictType_ID { get; set; }

        /// <summary>
        /// 類型名稱
        /// </summary>
        public virtual string Name { get; set; }

        /// <summary>
        /// 指定值
        /// </summary>
        public virtual string Value { get; set; }

        /// <summary>
        /// 備注
        /// </summary>
        public virtual string Remark { get; set; }
    }

這個類文件,我們一般把這個業務模塊相關的統一放在一個文件中,例如字典數據相關的DTO放在一個DictDataDto文件里面,方便管理,如下所示。

上面是字典模塊的一些基礎介紹,實際上我們開發業務模塊的時候,錄入數據的時候,還需要一個判斷的步驟,如不允許名稱重復的情況。在創建新的記錄和更新已有記錄都需要進行必要的判斷,保證數據的有效性和不重復性。

如對于省份管理界面來說,我們不能運行重復錄入省份名稱,那么就需要在錄入數據或者更新數據的時候,進行必要的存在性判斷。

image

那么上面的處理是如何實現的呢。

主要的界面實現代碼如下所示。

if (string.IsNullOrEmpty(ID))
{
    //判斷存在條件
    var countDto = new ProvincePagedDto() { ProvinceName = this.txtProvince.Text };
    bool isExist = await ProvinceApiCaller.Instance.Count(countDto) > 0;
    if (isExist)
    {
        MessageDxUtil.ShowTips("省份名稱已存在,請選擇其他名稱");
        this.txtProvince.Focus();
        return;
    }
    else
    {
        //創建新記錄
        tempInfo = await ProvinceApiCaller.Instance.Create(tempInfo);
    }
}
else
{
    //判斷存在條件,排除本記錄同名情況
    var countDto = new ProvincePagedDto() { ProvinceName = this.txtProvince.Text, ExcludeId = ID.ToInt64() };
    bool isExist = await ProvinceApiCaller.Instance.Count(countDto) > 0;
    if (isExist)
    {
        MessageDxUtil.ShowTips("省份名稱已存在,請選擇其他名稱");
        this.txtProvince.Focus();
        return;
    }
    else
    {
        //更新記錄
        tempInfo = await ProvinceApiCaller.Instance.Update(tempInfo);
    }
}

ProcessDataSaved(this.btnOK, new EventArgs());
this.DialogResult = System.Windows.Forms.DialogResult.OK;

我們發現,這里增加了一個Count的函數用來判斷,傳入的條件就是前面的分頁請求條件。

bool isExist = await ProvinceApiCaller.Instance.Count(countDto) > 0;

我們看看我們的應用服務層的接口實現如下所示。

        /// <summary>
        /// 獲取指定條件的數量
        /// </summary>
        /// <param name="input">查找條件</param>
        /// <returns></returns>
        public async virtual Task<int> Count(TGetAllInput input)
        {
            var query = CreateFilteredQuery(input);
            return await Task.FromResult(query.Count());
        }

這里最終還是跳轉到 CreateFilteredQuery 函數里面實現判斷邏輯了。

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

這里面包含了兩個判斷條件,一個是排除指定的ID記錄,一個是匹配省份名稱。

因為我們在更新記錄的時候,需要判斷非本記錄是否有重復的名稱。

//判斷存在條件,排除本記錄同名情況
var countDto = new ProvincePagedDto() { ProvinceName = this.txtProvince.Text, ExcludeId = ID.ToInt64() };
bool isExist = await ProvinceApiCaller.Instance.Count(countDto) > 0;

這個ExcludeId 我們在分頁條件里面增加一個固定的屬性即可。

image

以上的分頁信息,包含了實體DTO對象的一些屬性,我們可以根據需要增加或者減少一部分屬性。

另外我們定義的創建省份Dto對象和獲取到單個實體的DTO對象,他們的定義和關系如下所示,方便我們在界面上進行操作。

    /// <summary>
    /// 創建全國省份表,DTO對象
    /// </summary>
    public class CreateProvinceDto : EntityDto<long>
    { 
        /// <summary>
        /// 默認構造函數(需要初始化屬性的在此處理)
        /// </summary>
        public CreateProvinceDto()
        {
         }

        #region Property Members
        
        /// <summary>
        /// 省份名稱
        /// </summary>
        [Required]
        public virtual string ProvinceName { get; set; }


        #endregion

    }

    /// <summary>
    /// 全國省份表,DTO對象
    /// </summary>
    public class ProvinceDto : CreateProvinceDto
    {

    }

固定這些規則后,我們也可以用代碼生成工具快速生成對應的DTO文件了。

有了這些分頁屬性后,我們就可以在應用服務層里面定義自己的過濾規則了,如對于字典類型的應用服務層的篩選條件函數,如下所示。

        /// <summary>
        /// 自定義條件處理
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        protected override IQueryable<DictType> CreateFilteredQuery(DictTypePagedDto input)
        {
            return base.CreateFilteredQuery(input)
                .WhereIf(!string.IsNullOrEmpty(input.ExcludeId), t => t.Id != input.ExcludeId) //不包含排除ID
                .WhereIf(!string.IsNullOrEmpty(input.Name), t => t.Name.Contains(input.Name))
                .WhereIf(!string.IsNullOrEmpty(input.Remark), t => t.Remark.Contains(input.Remark))
                .WhereIf(!string.IsNullOrEmpty(input.Code), t => t.Code == input.Code)
                .WhereIf(!string.IsNullOrEmpty(input.PID), t => t.PID == input.PID);
        }

上面是對于包含、相等或者不等于的三種情況的條件判斷,如果我們還需要一個時間區間范圍或者數值范圍的判斷,那么同樣可以在這里進行管理規則,如下是針對產品應用服務層的過濾規則,如下代碼所示。

        /// <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
                 
                 //狀態
                .WhereIf(input.Status.HasValue, t => t.Status==input.Status)
                                                                                              
                 //成本價區間查詢
                .WhereIf(input.PriceStart.HasValue, s => s.Price >= input.PriceStart.Value)
                .WhereIf(input.PriceEnd.HasValue, s => s.Price <= input.PriceEnd.Value)

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

                //特價區間查詢
                .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
                                                                                                  
                //最低折扣區間查詢
                .WhereIf(input.LowestDiscountStart.HasValue, s => s.LowestDiscount >= input.LowestDiscountStart.Value)
                .WhereIf(input.LowestDiscountEnd.HasValue, s => s.LowestDiscount <= input.LowestDiscountEnd.Value)

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

以上就是我們深入對分頁查詢和判斷是否存在接口的細節處理,可以包含很多自定義的條件,如等于或不等于、包含或者不包含,區間查詢(大于或者小于等)條件的處理。對于省份城市行政區管理模塊的重復性判斷,我們通過Count函數來判斷,同時在后臺應用服務層對這些參數進行規則過濾即可。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容