首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

動態構建 Lambda 表達式:靈活應對不確定查詢條件

     編輯:關於.NET

前言

在實際開發中,經常會遇到查詢條件不固定的情況:用戶可能只輸入姓名,也可能同時指定姓名、性別、年齡等多個欄位。傳統寫死 SQL 或 Lambda 的方式顯得死板且難以維護。本文介紹如何利用 System.Linq.Expressions 命名空間,在運行時動態構建 Lambda 表達式,實現靈活的動態查詢。

核心類別設計:ConstructLambda<T>

我們封裝一個泛型類別 ConstructLambda<T>,約束 T 為參考類型且擁有無參構造函數。該類別提供兩個核心方法:

  • GetAndLambdaExpression:以 AND 邏輯串聯多個條件
  • GetOrLambdaExpression:以 OR 邏輯串聯多個條件

關鍵實現細節

public Expression<Func<T, bool>> GetAndLambdaExpression(Dictionary<string, string> dictionary)
{
    // 1. 起始常量:True(AND 的單位元)
    Expression expressionReturn = Expression.Constant(true);
    // 2. 參數表達式:p => ...
    ParameterExpression param = Expression.Parameter(typeof(T), "p");

    foreach (string key in dictionary.Keys)
    {
        // 3. 取得屬性:p.Name
        MemberExpression property = Expression.Property(param, typeof(T).GetProperty(key));
        // 4. 呼叫 ToString():p.Name.ToString()
        MethodCallExpression toStringCall = Expression.Call(property, typeof(T).GetMethod("ToString"));
        // 5. 建立常數:值
        ConstantExpression constant = Expression.Constant(dictionary[key]);
        // 6. 比較:p.Name.ToString() == "JT"
        BinaryExpression equal = Expression.Equal(toStringCall, constant);
        // 7. 累積 AND
        expressionReturn = Expression.And(expressionReturn, equal);
    }

    // 8. 封裝成 Lambda<T, bool>
    return Expression.Lambda<Func<T, bool>>(expressionReturn, param);
}

GetOrLambdaExpression 邏輯類似,僅將起始常量改為 false、累積運算改為 Expression.Or。

實戰演示

測試實體

public class Person
{
    public string Name { get; set; }
    public string Sex { get; set; }
    public int Age { get; set; }
    public DateTime Birthday { get; set; }
}

查詢字典

var dict = new Dictionary<string, string>
{
    {"Name", "JT"}, {"Sex", "男"}, {"Age", "20"}, {"Birthday", "02/02/2008"}
};

執行結果

場景方法生成的 Lambda 表達式
無條件 AND p => True
OR p => False
多條件 AND p => ((((True And p.Name.ToString() == "JT") And p.Sex.ToString() == "男") And p.Age.ToString() == "20") And p.Birthday.ToString() == "02/02/2008")
OR p => ((((False Or p.Name.ToString() == "JT") Or p.Sex.ToString() == "男") Or p.Age.ToString() == "20") Or p.Birthday.ToString() == "02/02/2008")

應用場景與優化建議

  • Entity Framework / LINQ to SQL:生成的 Expression<Func<T, bool>> 可直接傳給 Where,由提供者翻譯為 SQL。
  • 類型安全:建議在構建前驗證字典鍵是否為實體的公開屬性,避免運行時拋出 NullReferenceException。
  • 數值/日期比較:目前統一轉字串比較,若需精確比較,可根據屬性 PropertyType 動態選擇 Expression.Equal、Expression.GreaterThan 等運算子。
  • 效能:同一查詢模式重複使用時,可緩存編譯後的 Func<T, bool> 或表達式樹本身。

結語

動態構建 Lambda 表達式讓查詢邏輯從「寫死」走向「配置化」,極大提升系統靈活度。掌握 System.Linq.Expressions 是進階 .NET 開發者的必修課,歡迎在留言區交流更多實戰技巧。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved