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

LINQ to SQL 執行期動態建構查詢條件三種做法

     編輯:關於.NET

情境說明

查詢時常需根據使用者輸入動態組合 WHERE 條件。LINQ to SQL 雖強型別,但動態建構條件比拼接 SQL 字串稍顯繁瑣。本文介紹三種方法,目標皆為:從 Northwind Customers 表找出 CompanyName 包含 keywords 陣列中任一關鍵字的資料。

方法一:運算式樹

手動建構 Expression<Func<Customers, bool>>,最貼近 LINQ 本質,效能最佳。

public static IEnumerable<Customers> GetCustomersFunc1(string[] keywords) {
    DataClassesDataContext dc = new DataClassesDataContext();

    // 參數表達式:c => ...
    ParameterExpression c = Expression.Parameter(typeof(Customers), "c");

    // 初始條件為 false (邏輯 OR 起始值)
    Expression condition = Expression.Constant(false);

    foreach (string keyword in keywords) {
        // c.CompanyName.Contains(keyword)
        Expression con = Expression.Call(
            Expression.Property(c, typeof(Customers).GetProperty("CompanyName")),
            typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),
            Expression.Constant(keyword)
        );

        // 邏輯 OR 累加
        condition = Expression.Or(con, condition);
        // 若需 AND 則用 Expression.And,並將初始值改為 true
    }

    // 建立 Lambda:c => condition
    Expression<Func<Customers, bool>> end = Expression.Lambda<Func<Customers, bool>>(condition, new ParameterExpression[] { c });

    var result = dc.Customers.Where(end);
    return result;
}

方法二:System.Linq.Dynamic 動態 LINQ

引用 Dynamic.cs (隨 LINQ Samples 提供),以字串形式撰寫條件,語法直觀。

public static IEnumerable<Customers> GetCustomersFunc2(string[] keywords) {
    DataClassesDataContext dc = new DataClassesDataContext();
    string queryString = "";

    foreach (string keyword in keywords) {
        // 產生:CompanyName.Contains("keyword1") or CompanyName.Contains("keyword2") or ...
        queryString += "CompanyName.Contains(\"" + keyword + "\") or ";
    }

    // 避免尾端 "or" 語法錯誤,加上永假條件
    queryString += "1=0";

    return dc.Customers.Where(queryString);
}

方法三:偽 LINQ - 字串拼接 SQL

本質仍是拼接 SQL,但透過 ExecuteQuery<T> 映射回實體,適合極複雜或效能敏感情境。

public static IEnumerable<Customers> GetCustomersFunc3(string[] keywords) {
    DataClassesDataContext dc = new DataClassesDataContext();
    string sqlQuery = "SELECT [CustomerID], [CompanyName], ... FROM [dbo].[Customers] WHERE ";

    foreach (string keyword in keywords) {
        sqlQuery += "([CompanyName] LIKE '%" + keyword + "%') OR ";
    }
    sqlQuery += "(1=0)";

    return dc.ExecuteQuery<Customers>(sqlQuery);
}

比較與建議

方法優點缺點適用情境
運算式樹強型別、效能最好、編譯時期檢查程式碼較冗長、需熟悉 Expression API核心查詢邏輯、高效能需求
Dynamic LINQ語法簡潔、接近原生 LINQ、支援排序/分組字串執行時期才驗證、需額外引用 Dynamic.cs動態報表、使用者自訂篩選
拼接 SQL完全控制 SQL、可用資料庫特有功能失去型別安全、SQL Injection 風險、維護困難極複雜查詢、舊系統遷移、效能微調

總結

優先考慮運算式樹或 Dynamic LINQ,保持型別安全與可維護性。僅在必要時退而求其次使用 SQL 字串。完整範例請參考原文程式碼註解。

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