2025-11-04
C#
00

目录

安装与环境配置
基本查询构造示例
指定单列与使用别名
批量指定列(支持前缀处理)
批量选择列
多表联接(Join)示例
Insert 示例
总结

KnightMoves.SqlObjects 是一个 .NET NuGet 包库,用于实现基于对象的 SQL 生成器。与其他依赖字符串操作(如串联和插值)的 SQL 构建器不同,此库采用包装 SQL 语法为 C# 对象的方法,从而让整个 SQL 查询由对象组成。这种方式带来了如下优势:

  • 语法匹配(Syntax Matching): 库的方法基本上和 SQL 语法保持一致,你可以用接近 SQL 的方式思考和编码。
  • 类型安全与 IntelliSense 支持: 通过对象构造查询,能够获得良好的编辑器提示和编译时检查,降低拼接 SQL 字符串所产生的错误风险。
  • 灵活性与扩展性: 除了支持 SELECT、FROM、JOIN 等基本操作外,还支持批量指定列、设置别名和构造复杂联接条件等特性。

安装与环境配置

首先,在 Visual Studio 中创建一个简单的 Console 应用程序,并通过 NuGet 安装 KnightMoves.SqlObjects 包。步骤如下:

  1. 右击项目的 “Dependencies/引用” 节点。
  2. 选择 “Manage NuGet Packages…”,搜索 “KnightMoves.SqlObjects” 并安装最新版。

安装完成后,在代码中加入如下 using 声明即可开始使用:

C#
using KnightMoves.SqlObjects;

image.png


基本查询构造示例

构造一个基本的 SELECT * FROM Products 查询非常简单。下面这个例子展示了如何通过静态类 TSQL 来生成 SQL 查询。

C#
using KnightMoves.SqlObjects; namespace AppKnightMoves { internal class Program { static void Main(string[] args) { var query = TSQL.SELECT() .FROM("Products").Build(); // 输出生成的 SQL 字符串 Console.WriteLine(query); } } }

image.png

这段代码展示了如何快速构造一个没有列过滤的 SQL 查询。


指定单列与使用别名

在实际的开发中,我们经常需要指定查询中的具体列,并为部分列设置别名。KnightMoves.SqlObjects 提供了 COLUMN() 方法和链式调用 .AS() 来实现这一功能。

C#
using KnightMoves.SqlObjects; namespace AppKnightMoves { internal class Program { static void Main(string[] args) { // 利用 COLUMN() 方法指定每个查询列, var query = TSQL.SELECT() .COLUMN("ProductID").AS("Id") .COLUMN("ProductName") .COLUMN("Price") .FROM("Products").Build(); Console.WriteLine(query); } } }

image.png

此外,有些情况下可以直接在 COLUMN() 方法中传递第三个参数作为别名(取决于具体实现),这为代码的简洁性提供了另一种选择。


批量指定列(支持前缀处理)

如果需要在查询中指定多个列,重复调用 COLUMN() 方法显得比较繁琐。借助复数形式的 COLUMNS() 方法,你可以一次性传入一个列名集合,甚至添加表的前缀来帮助区分不同表中的列。

批量选择列

下面的代码展示了如何用一个字符串数组一次性构造查询列:

C#
using KnightMoves.SqlObjects; using KnightMoves.SqlObjects.SqlCode.TSQL; namespace AppKnightMoves { internal class Program { static void Main(string[] args) { var columns = new List<TSQLColumn> { new TSQLColumn { MultiPartIdentifier = "p", ColumnName = "ProductID" }, new TSQLColumn { MultiPartIdentifier = "p", ColumnName = "ProductName", Alias = "Name" } }; var sql = TSQL .SELECT() .COLUMNS(columns) .FROM("dbo", "Products", "p") .Build(); Console.WriteLine(sql); } } }

image.png

这种方式在写联接查询时尤其有用,可以避免列名称的混淆,提高代码可读性。


多表联接(Join)示例

很多业务场景需要从多个表中联合查询数据。以下示例展示了如何通过库中的 INNERJOIN() 方法构造一个内联接查询,同时使用 ON()IsEqualTo() 方法来指定联接条件。

假设我们的目标 SQL 如下:

SQL
SELECT [p].[ProductID], [p].[ProductName], [c].[CategoryName] FROM [Products] AS [p] INNER JOIN [Categories] AS [c] ON [p].[CategoryID] = [c].[CategoryID]

对应的 C# 示例代码如下:

C#
using KnightMoves.SqlObjects; using KnightMoves.SqlObjects.SqlCode.TSQL; namespace AppKnightMoves { internal class Program { static void Main(string[] args) { // 构造 SELECT 子句,分别指定来自两个表的查询列(使用别名区分) var query = TSQL.SELECT() .COLUMN("ProductID", "p") // 来自 Products 表,别名为 p .COLUMN("ProductName", "p") // 来自 p 表 .COLUMN("CategoryName", "c") // 来自 Categories 表,别名为 c .FROM("Products", "p") // 主表及其别名 // 使用 INNERJOIN() 加入 Categories 表,并指定别名 c .INNERJOIN("Categories", "c") // 使用 ON() 方法构造联接条件 .ON( "c", "CategoryID" ).IsEqualTo("p", "CategoryID").Build(); Console.WriteLine(query); } } }

image.png

在这个例子中,我们看到:

  • 每个表均通过 FROM 或 INNERJOIN 指定,并传递别名;
  • 列引用也同时包含了相应的表前缀;
  • 联接条件通过链式调用 .IsEqualTo() 来构造,尽管语法上略有区别,但整体思路与 SQL 相近。

Insert 示例

C#
using KnightMoves.SqlObjects; using KnightMoves.SqlObjects.SqlCode.TSQL; namespace AppKnightMoves { internal class Program { static void Main(string[] args) { // 构造 INSERT 子句,向 Products 表插入一条新记录 var query = TSQL.INSERT().INTO("Products") .COLUMN("ProductName").VALUE("苹果") .COLUMN("CategoryID").VALUE(1) .COLUMN("UnitPrice").VALUE(5.50M) .Build(); Console.WriteLine(query); } } }

image.png

总结

KnightMoves.SqlObjects 通过对象化的构建方式,实现了几乎完全匹配 T-SQL 语法的查询生成。尽管某些细节(例如使用 COLUMN() 方法和 IsEqualTo() 操作符)与直接编写 SQL 略有出入,但这正是为了让开发者能够直接以 SQL 思维来编写代码,同时获得编译时类型安全和更好的 IDE 支持。


希望本文能够帮助你快速上手 KnightMoves.SqlObjects,并在实际开发中获得更高的生产力与代码质量。欢迎继续探索、尝试并分享你的使用经验!

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!