动态拼接表达式——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: