動態拼接表達式——Expression

我們在項目中會遇到以下查詢需求嗎?

比如需要查詢出滿足以下條件的會員:

 條件組一:30-40歲的男性會員

 條件組二:20-30歲的女性會員

 條件組三:60-80歲性別未知的會員

 條件組內是並且關係,但是條件組與組之間是或者關係。 

很多程式設計師腦袋可能會直接蹦出用where拼接條件組的想法,就如同下面圖片所展示的方法 :

 

生成的SQl語句:

 

根據生成的sql語句我們會發現直接使用Where拼接出來的sql語句是並且的關係,

原本我們想要的結果是組與組之間是或者的關係,但是現在變成了並且的關係,很顯然不滿足我們的查詢需求。

想要達到我們的查詢需求,我們得使用動態拼接條件的方法,通常我會使用Expression

 

最終我們生成的sql語句為:

 從查詢語句可以看出達到了我們的查詢需求,組與組之間是或者的關係。 

以下是舉例程式碼:

namespace HKERP.CRM.Application.CRMManagement
{
    /// <summary>
    /// 動態拼接表達式
    /// </summary>
    public class ExpressionTest : ApplicationService
    {
        public readonly IRepository<CrmMember, int> _memberRep;
        public ExpressionTest(IRepository<CrmMember, int> memberRep)
        {
            _memberRep = memberRep;

        }

        /// <summary>
        /// 測試
        /// </summary>
        [AbpAuthorize]
        public async  Task  Test()
        {           

            #region 封裝查詢條件

            var param = new List<SearchMemberInputDto>
            {
                new SearchMemberInputDto { Sex = 1, AgeStart = 30, AgeEnd = 40 },// 30-40歲的男性
                new SearchMemberInputDto { Sex = 2, AgeStart = 20, AgeEnd = 30 }, // 20-30歲的女性
                new SearchMemberInputDto { Sex = 2, AgeStart = 20, AgeEnd = 30 }// 60-80歲性別未知
            };

            #endregion

            #region 動態拼接

            var members = (await _memberRep.GetAllAsync()).Where(a=>a.GroupId==AbpSession.GroupId && a.IsDeleted==false);

            Expression<Func<CrmMember, bool>> expressions = s => false;

            foreach (var item in param)
            {                
                expressions = expressions.Or(s => s.Sex == item.Sex && s.Age >=item.AgeStart && s.Age<=item.AgeEnd);
            }

            members = members.Where(expressions);

            var memberList = members.ToList();
          
            #endregion

        }
    }

   /// <summary>
   /// 條件
   /// </summary>
    public class SearchMemberInputDto
    {

        /// <summary>
        /// 性別
        ///0-未知; 1-男;2-女
        /// </summary>
        public int Sex { get; set; }

        /// <summary>
        /// 年齡-開始值
        /// </summary>
        public int AgeStart { get; set; }

        /// <summary>
        /// 年齡-結束值
        /// </summary>
        public int AgeEnd { get; set; }
    }

}

View Code

這個是很簡單的一種用法,我這裡只做了簡單的講述,希望對大家有所幫助。

Tags: