QueryLens 1.1.3

dotnet add package QueryLens --version 1.1.3
                    
NuGet\Install-Package QueryLens -Version 1.1.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="QueryLens" Version="1.1.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="QueryLens" Version="1.1.3" />
                    
Directory.Packages.props
<PackageReference Include="QueryLens" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add QueryLens --version 1.1.3
                    
#r "nuget: QueryLens, 1.1.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package QueryLens@1.1.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=QueryLens&version=1.1.3
                    
Install as a Cake Addin
#tool nuget:?package=QueryLens&version=1.1.3
                    
Install as a Cake Tool

QueryLens

Stop finding SQL bugs in production. Catch them in your tests.

Column typos. Misspelled table names. Functions that don't exist in your SQL Server version. Parameter mismatches. These bugs hide in raw SQL strings, slip past the compiler, and blow up at runtime — usually in production, usually at the worst time.

QueryLens validates your hand-written SQL at test time, giving Dapper, ADO.NET, and query-registry codebases a real validation surface — without an ORM, without generated code, without changing how you write SQL.

.NET 9 License: MIT


Get Started in 30 Seconds

dotnet add package QueryLens
var query = new SqlQuery("SELECT name FROM customers LIMIT 10");

Assert.True(query.IsValid);   // structurally sound SQL — validated, done

That's it. No configuration, no database connection, no ceremony. QueryLens parses and validates your SQL right inside your test suite.

But that's just the beginning.


Three Levels of Confidence

QueryLens meets you where you are and scales up as you need it. Each level builds on the last — start simple, go deep when you're ready.

Level What You Set What You Get
1 — Syntax Nothing Catches structurally broken SQL across all supported dialects
2 — Dialect QueryLens.Dialect Everything in Level 1, plus function validation, version-gated checks, and reserved-word warnings
3 — Schema QueryLens.LoadDbSchemaFrom(...) Everything in Level 2, plus real column names, table existence, and stored procedure checks

Level 1: Catch Broken SQL with Zero Setup

var query = new SqlQuery("SELECT name FROM customers LIMIT 10");

Assert.True(query.IsValid);

Level 1 is deliberately permissive. Without a dialect, QueryLens accepts common syntax across supported engines and only rejects SQL that is structurally broken. Perfect for a quick safety net across any codebase.

Level 2: Lock Down Your Dialect

QueryLens.Dialect = DialectProfile.SqlServer2017;

var query = new SqlQuery("SELECT STRING_AGG(name, ',') FROM departments");

Assert.True(query.IsValid);  // STRING_AGG exists in SQL Server 2017 — all clear

Set a dialect and QueryLens gets strict: built-in function validation, version-gated function availability, reserved-word warnings, and dialect-specific syntax behavior. That STRING_AGG call would fail validation against SQL Server 2016 — exactly the kind of bug you want to find before deployment.

Level 3: Validate Against Your Real Schema

QueryLens.Dialect = DialectProfile.SqlServer2017;
QueryLens.LoadDbSchemaFrom(connectionString);

var query = new SqlQuery("SELECT id, missing_column FROM customers");

Assert.False(query.IsValid);
Assert.Contains(query.Errors, issue => issue.Code == "QL0011");

Schema loading takes a one-time snapshot of your database and validates against that immutable in-memory copy. QueryLens does not hit the database on every validation call — it's fast, deterministic, and safe for parallel test execution.


Validate Every SQL Statement in Your Entire Project — at Once

This is the power feature. Mark your SQL constants with attributes, then validate your whole assembly in a single test.

public static class OrderQueries
{
    [SqlQuery]
    public static readonly string GetById = "SELECT id, total FROM orders WHERE id = @Id";

    [SqlInsert]
    public static readonly string Create = "INSERT INTO orders (id, total) VALUES (@Id, @Total)";

    [SqlUpdate]
    public static readonly string UpdateTotal = "UPDATE orders SET total = @Total WHERE id = @Id";

    [SqlDelete]
    public static readonly string Remove = "DELETE FROM orders WHERE id = @Id";
}
QueryLens.Dialect = DialectProfile.SqlServer2017;

var result = QueryLens.ValidateAssembly(typeof(OrderQueries).Assembly);

Assert.True(result.AllValid);

ValidateAssembly discovers every field, property, and method decorated with [SqlQuery], [SqlInsert], [SqlUpdate], [SqlDelete], [SqlMerge], or [SqlStoredProc] and validates each one against the active QueryLens level. One test. Every SQL statement. Full coverage.


Drops Right Into Dapper

All statement wrappers implicitly convert to string, so they work seamlessly with Dapper and ADO.NET — no adapters, no extra steps.

await connection.QueryAsync<Customer>(
    new SqlQuery("SELECT * FROM customers WHERE status = @Status"),
    new { Status = "active" });

Supported wrappers: SqlQuery | SqlInsert | SqlUpdate | SqlDelete | SqlMerge | SqlStoredProc


Core API

QueryLens.Dialect = DialectProfile.SqlServer2019;
QueryLens.LoadDbSchemaFrom(connectionString);

var query = new SqlQuery("SELECT * FROM dbo.orders WHERE order_id = @Id");

var isValid = query.IsValid;
var errors = query.Errors;
var warnings = query.Warnings;
var summary = query.ErrorSummary;

Facade members:

Member Purpose
QueryLens.Dialect Set the target SQL dialect and version
QueryLens.HasLoadedSchema Check if a schema snapshot is active
QueryLens.IsFrozen Check if configuration is locked
QueryLens.LoadDbSchemaFrom(...) Load a schema snapshot from a connection string
QueryLens.LoadDbSchemaFromAsync(...) Async variant of schema loading
QueryLens.RefreshDbSchema() Replace the current schema snapshot
QueryLens.ClearDbSchema() Remove the loaded schema
QueryLens.Reset() Unfreeze and clear all configuration
QueryLens.ValidateAssembly(assembly) Validate all attributed SQL in an assembly

Built for Test Suites

QueryLens is designed to be fast and predictable inside your test runner:

  • Lazy parsing — nothing happens until you ask for validation
  • Cached results — parsed output and validation results are cached
  • Zero runtime cost — code that never touches validation pays nothing
  • Freeze model — configuration is mutable until first validation, then locks. This keeps cached results deterministic and safe under parallel test execution. Call QueryLens.Reset() to unfreeze.

Documentation

License

MIT

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.3 741 4/12/2026
1.1.3-preview.40 50 5/3/2026
1.1.2 97 4/12/2026
1.1.1 98 4/12/2026
1.1.0 102 4/12/2026
1.0.0 126 4/11/2026
1.0.0-preview.10 66 4/7/2026
1.0.0-preview.9 55 4/5/2026
1.0.0-preview.8 66 4/5/2026
1.0.0-preview.7 50 4/5/2026
1.0.0-preview.6 63 4/5/2026
1.0.0-preview.4 57 4/4/2026
1.0.0-preview.3 73 4/4/2026
1.0.0-preview.1 60 4/2/2026

v1.1.3: Fixed two parser false-positives — QL0001 no longer fires on COALESCE with a subquery as a non-first argument (depth tracker now breaks on ) at depth 0), and QL0070 no longer fires on ANY/ALL/SOME PostgreSQL array operators (added to NonFunctionKeywords).