我們在專案中會遇到以下查詢需求嗎?

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

條件組一: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; }
} }

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