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

C# 建構複雜 SQL 查詢的利器:SelectQueryBuilder 實現參數化、防注入與動態組裝

     編輯:關於C#

痛點:字串拼接的隱患

傳統以字串拼接建構 SQL 查詢,不僅程式碼難讀、難維護,更極易引入 SQL 注入 風險:

string sql = "SELECT * FROM Customers WHERE 1=1";
if (!string.IsNullOrEmpty(name)) sql += " AND Name LIKE '" + name + "%'";
if (city != null) sql += " AND City = '" + city + "'"; // 直接拼接使用者輸入

存儲過程僅將問題轉移到資料庫層,動態 SQL 仍需拼接,注入風險依存。

SelectQueryBuilder:流式 API 構建安全查詢

SelectQueryBuilder 提供強型別、鏈式呼叫介面,自動處理參數化、條件組合、JOIN、分組排序等複雜邏輯,最終輸出參數化 SQL 或 DbCommand 物件。

基礎查詢建構

var q = new SelectQueryBuilder();
q.SelectFromTable("Customers")
 .SelectAllColumns()
 .TopRecords = maxRecords;

if (!string.IsNullOrEmpty(name))
    q.AddWhere("CompanyName", Comparison.Like, name + "%");
if (city != null)
    q.AddWhere("City", Comparison.Like, city + "%");
if (country != null)
    q.AddWhere("Country", Comparison.Equals, country);

// 產生參數化 SQL
string sql = q.BuildQuery();
// 或直接產生 DbCommand(自動參數化,防注入)
q.SetDbProviderFactory(DbProviderFactories.GetFactory("System.Data.SqlClient"));
DbCommand cmd = q.BuildCommand();

SQL 函數與字面值:SqlLiteral

需直接嵌入資料庫函數(如 GETDATE())而不被加引號:

q.AddWhere("OrderDate", Comparison.LessOrEquals, new SqlLiteral("GETDATE()"));
// 生成:WHERE OrderDate <= GETDATE()

多表 JOIN

q.SelectFromTable("Orders")
 .AddJoin(JoinType.InnerJoin, "Customers", "CustomerID", Comparison.Equals, "Orders", "CustomerID")
 .AddWhere("Customers.City", Comparison.Equals, "London");
// 生成:INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID

聚合與 HAVING

q.SelectColumns("COUNT(*) AS Count", "ShipCity")
 .SelectFromTable("Orders")
 .GroupBy("ShipCity")
 .AddHaving("ShipCity", Comparison.NotEquals, "Amsterdam")
 .AddOrderBy("COUNT(*)", Sorting.Descending);

多層級 WHERE 條件(AND/OR 巢狀)

支援類似 SQL Server 查詢設計器的「準則/Or 欄」邏輯:

// 第 1 層:AND 關係
q.AddWhere("CustomerID", Comparison.Equals, "VINET", 1);
q.AddWhere("OrderDate", Comparison.LessThan, new DateTime(2005,1,1), 1);

// 第 2 層:OR 關係
q.AddWhere("CustomerID", Comparison.Equals, "TOMSP", 2);
q.AddWhere("OrderDate", Comparison.LessThan, new DateTime(2004,6,30), 2);

// 第 3 層:另一組 OR
q.AddWhere("CustomerID", Comparison.Equals, "TOMSP", 3);
q.AddWhere("OrderDate", Comparison.GreaterThan, new DateTime(2006,1,1), 3);

// 生成:WHERE (層1條件) OR (層2條件) OR (層3條件)

巢狀條件子句

var clause = q.AddWhere("OrderDate", Comparison.LessThan, new DateTime(2004,6,30), 2);
clause.AddClause(LogicOperator.Or, Comparison.GreaterThan, new DateTime(2006,1,1));
// 生成:(OrderDate < '2004-06-30' OR OrderDate > '2006-01-01')

擴充生態:完整的查詢建構器家族

框架同步提供 InsertQueryBuilder、UpdateQueryBuilder、DeleteQueryBuilder,統一風格覆蓋 CRUD 全場景。原始碼與 DLL 可從 CodeEngine 獲取。

總結

拒絕字串拼接,擁抱 SelectQueryBuilder:

  • 安全:原生參數化,徹底防注入
  • 可讀:流式 API,邏輯清晰對應 SQL 結構
  • 靈活:支援複雜 JOIN、巢狀條件、函數、分頁、聚合
  • 可移植:抽象 DbProviderFactory,支援多種資料庫
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved