动态拼接表达式——Expression

时间:2021-02-01 04:33:01

我们在项目中会遇到以下查询需求吗?

比如需要查询出满足以下条件的会员:

条件组一:30-40岁的男性会员

条件组二:20-30岁的女性会员

条件组三:60-80岁性别未知的会员

条件组内是并且关系,但是条件组与组之间是或者关系。

很多程序员脑袋可能会直接蹦出用where拼接条件组的想法,就如同下面图片所展示的方法 :

动态拼接表达式——Expression

生成的SQl语句:

动态拼接表达式——Expression

根据生成的sql语句我们会发现直接使用Where拼接出来的sql语句是并且的关系,

原本我们想要的结果是组与组之间是或者的关系,但是现在变成了并且的关系,很显然不满足我们的查询需求。

想要达到我们的查询需求,我们得使用动态拼接条件的方法,通常我会使用Expression

动态拼接表达式——Expression

最终我们生成的sql语句为:

动态拼接表达式——Expression

从查询语句可以看出达到了我们的查询需求,组与组之间是或者的关系。

以下是举例代码:

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

这个是很简单的一种用法,我这里只做了简单的讲述,希望对大家有所帮助。