表達式樹擴展 動態生成表達式樹插件 Sy.ExpressionBuilder。


       CURD中,基礎查詢我感覺還是很煩人的一個浪費時間的工作,我經歷過遠古時代的GetAll(string name,int age),這種方式寫服務的時候真的是心中一萬個草泥馬飛過,后面逐漸的變成了傳一個實體GetAll([FromQuery] GetDto)似乎也能默默的忍受,然后含淚寫着一堆的WhereIf,目前這種方式應該還是很多人在用的一種方式。作為新生代的農民工,我們是自然不能忍受一直這樣,於是就有Sy.ExpressionBuilder(大家可以去nuget下載試用)這個查詢插件,似乎我們有了更好的選擇。 

      為了方便后面的介紹,先讓我們有幾個實體,用戶表,角色表,系統表,我們約定一個用戶只有一種角色,但是可以存在多個系統中。
     

 /// <summary>
    /// 用戶表
    /// </summary>
    public class Manager
    {
        /// <summary>
        /// 編號
        /// </summary>
        public string Id { get; set; }

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

        /// <summary>
        /// 手機
        /// </summary>
        public string Tel { get; set; }

        /// <summary>
        /// 角色編號
        /// </summary>
        public string RoleId { get; set; }

        /// <summary>
        /// 角色
        /// </summary>
        public Role Role { get; set; }


        /// <summary>
        /// 系統
        /// </summary>
        public List<Sys> Sys { get; set; }

        /// <summary>
        /// 創建時間
        /// </summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 性別
        /// </summary>
        public EnumGender Gender { get; set; }
    }
/// <summary>
    /// 角色表
    /// </summary>
    public class Role
    {
        /// <summary>
        /// 角色名
        /// </summary>
        public string RoleName { get; set; }

        /// <summary>
        /// 角色編號
        /// </summary>
        public string Id { get; set; }


    }
    /// <summary>
    /// 系統表
    /// </summary>
    public class Sys
    {
        /// <summary>
        /// 系統名稱
        /// </summary>
        public string SysName { get; set; }

        /// <summary>
        /// 編號
        /// </summary>
        public string Id { get; set; }
    }
    /// <summary>
    /// 性別
    /// </summary>
    [Flags]
    public enum EnumGender
    {
        /// <summary>
        ////// </summary>
        Man = 1 << 0,


        /// <summary>
        ////// </summary>
        Women = 1 << 1,
    }

然后我們先創建張三李四兩個小伙伴

            List<Manager> list = new List<Manager>();
            List<Sys> Sys = new List<Sys>();
            List<Sys> Sys2 = new List<Sys>();
            Sys.Add(new Tests.Sys { Id = "1", SysName = "倉管系統" });
            Sys.Add(new Tests.Sys { Id = "2", SysName = "人力資源系統" });
            Sys2.Add(new Tests.Sys { Id = "1", SysName = "倉管系統" });

            list.Add(new Manager { Id = "1", UserName = "張三", Tel = "18888888888", Gender = EnumGender.Man, RoleId = "1", CreateTime = DateTime.Parse("2021-9-22 10:50:50"), Sys = Sys, Role = new Role { RoleName = "超級管理員", Id = "1" } });
            list.Add(new Manager { Id = "2", UserName = "李四", Tel = "16666666666", Gender = (EnumGender)3, RoleId = "2", CreateTime = DateTime.Parse("2021-9-21 10:50:50"), Sys = Sys2, Role = new Role { RoleName = "管理員", Id = "2" } });

數據結構圖

 

 

 

在做查詢前先讓我們定義查詢的Dto

 /// <summary>
    /// 查詢參數實體
    /// </summary>

    public class AllManagerDto : QueryPageModel
    {
        /// <summary>
        /// 創建時間 開始(時間必須以Start結尾)
        /// </summary>
        public DateTime? CreateTimeStart { get; set; }

        /// <summary>
        /// 創建時間  結束(結束時間必須以End結尾)
        /// </summary>
        public DateTime? CreateTimeEnd { get; set; }
        /// <summary>
        /// 創建時間(或者使用特性,約定方式)傳值為("2021-9-21,2021-10-7")中間用,分割
        /// </summary>
        [Condition("CreateTime", EnumCondition.Between)]
        public string CreateTime { get; set; }
 
         
/// <summary>
        /// 角色編號
        /// </summary>
        [Condition("Role.Id", EnumCondition.In)]
        public string RoleId { get; set; }

        /// <summary>
        /// 角色名稱
        /// </summary>

        [Condition("Role.RoleName", EnumCondition.Contains)]

        public string RoleName { get; set; }


        /// <summary>
        /// 系統名稱
        /// </summary>

        [Condition("Sys[SysName]", EnumCondition.Contains)]

        public string SysName { get; set; }


        /// <summary>
        /// 名稱
        /// </summary>
        public string UserName { get; set; }


        /// <summary>
        /// 性別
        /// </summary>

        public EnumGender? Gender { get; set; }


        [NotMapped]
        public string AA { get; set; }
        /// <summary>
        /// 年齡 開始(必須以Min結尾)
        /// </summary>
        public int? AgeMin { get; set; }

        /// <summary>
        /// 年齡  結尾(必須以Max結尾)
        /// </summary>
        public int? AgeMax{ get; set; }
 
         

 


    }

 

我們來做一個簡單的單表查詢,查詢完全滿足,名字叫張三,號碼為 18888888888,性別男,角色編號為“1”的,創建時間 大於 "2021-9-22" 的用戶。我們只需要一句話就可以了,想想你以前的得寫多少語句。

我們默認有以下約定 時間格式范圍為 <=和>= ,數字 int decimal double等為 <=和>=,string 為包含

  /// <summary>
        /// 單表查詢
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static List<Manager> GetAll(AllManagerDto input)
        {
            var list = GetList();
            input.RoleId = "1";
            input.Tel = "18888888888";
            input.UserName = "張三";
            input.Gender = EnumGender.Man;
            input.CreateTimeStart = DateTime.Parse("2021-9-22");

            var query = input.ToQueryModel<Manager>(); return list.AsQueryable().Where(query).ToList();
        }

我們看看效果

 

 生成的表達式

 

 返回結果,是不是很神奇。

 

 那如果我們要關聯表查詢呢,怎么破,別急,看下面代碼

       /// <summary>
        /// 角色名稱
        /// </summary>

        [Condition("Role.RoleName", EnumCondition.Contains)]

        public string RoleName { get; set; }


        /// <summary>
        /// 系統名稱
        /// </summary>

        [Condition("Sys[SysName]", EnumCondition.Contains)]

        public string SysName { get; set; }

我們使用 Condition 特性,標識 Role.RoleName 表示 查詢Role下 RoleName 等於我們要查的數據,Sys[SysName]  表示用戶表下Sys數組下名稱為SysName 的條件

 

 

這就基本包含了我們所用到的情況。你是不是覺得漏了點什么,我們要處理排序怎么處理,別急,我們內置了添加排序的方法,我們還可以添加多個,完美把

  /// <summary>
        /// 添加排序條件
        /// </summary>
        /// <returns></returns>
        public static BaseQueryModel AddOrderByItem(this BaseQueryModel queryModel, string propName, bool isDesc = true)
        {
            queryModel.OrderByItems.Add(new OrderByItem { PropName = propName, IsDesc = isDesc });
            return queryModel;
        }

 

 還有個分組的特性,等有人問再說.......



 



 
        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM