KnightMoves.SqlObjects is a .NET NuGet package that provides an object-oriented fluent SQL builder for use with ADO or Dapper.
Unlike traditional SQL builders that rely on string manipulation — such as concatenation and interpolation — this library takes a different approach. Instead of generating SQL strings, it encapsulates SQL syntax within C# objects, allowing entire queries to be constructed as object hierarchies. This approach offers greater flexibility and capabilities beyond what string-based methods can achieve.
Many ORMs and SQL builders introduce method names that differ from standard SQL terminology. In contrast, this library closely mirrors SQL syntax. The goal is to enable developers to think and code in SQL naturally, without needing to learn a new abstraction.
KnightMoves.SqlObjects fully supports all DML statements in Microsoft's T-SQL language.
Simple SQL query
A simple SELECT * FROM [Table]
would look like this:
using KnightMoves.SqlObjects;
var sql = TSQL
.SELECT()
.STAR()
.FROM("Products")
.Build();
Console.WriteLine(sql);
Since we are not dealing with strings here, KnightMoves.SqlObjects methods and signatures pop up in the intelicode features of the IDE, where you can search through the options to find what you're looking for easily:
Selection via specification of TSqlColumn
objects:
using System;
using System.Collections.Generic;
using KnightMoves.SqlObjects;
using KnightMoves.SqlObjects.SqlCode.TSQL;
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);
Of course you can join tables
var sql = TSQL
.SELECT()
.COLUMN("p", "ProductID")
.COLUMN("p", "ProductName")
.COLUMN("c", "CategoryName")
.COLUMN("s", "CompanyName")
.FROM("dbo", "Products", "p")
.LEFTJOIN("dbo", "Categories", "c").ON("c", "CategoryID").IsEqualTo("p", "CategoryID")
.LEFTJOIN("dbo", "Suppliers", "s").ON("s", "SupplierID").IsEqualTo("p", "SupplierID")
.Build();
Console.WriteLine(sql);
or performe subqueries:
var sql = TSQL
.SELECT()
.COLUMN("c", "CategoryID")
.COLUMN("c", "CategoryName")
.SubQueryStart()
.SELECT()
.COUNT("*")
.FROM("dbo", "Products", "p")
.WHERE()
.COLUMN("p", "CategoryID").IsEqualTo("c", "CategoryID").AND()
.COLUMN("p", "Discontinued").IsEqualTo(false)
.SubQueryEnd().AS("ActiveProducts")
.FROM("dbo", "Categories", "c")
.Build();
Console.WriteLine(sql);
Just head over to their documentation in order to see what's possible with KnightMoves.SqlObjects!