VQuery 1.0.6

dotnet add package VQuery --version 1.0.6
                    
NuGet\Install-Package VQuery -Version 1.0.6
                    
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="VQuery" Version="1.0.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="VQuery" Version="1.0.6" />
                    
Directory.Packages.props
<PackageReference Include="VQuery" />
                    
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 VQuery --version 1.0.6
                    
#r "nuget: VQuery, 1.0.6"
                    
#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 VQuery@1.0.6
                    
#: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=VQuery&version=1.0.6
                    
Install as a Cake Addin
#tool nuget:?package=VQuery&version=1.0.6
                    
Install as a Cake Tool

VQuery

A lightweight, high-performance database library for .NET โ€” one simple API for MySQL, PostgreSQL, and SQL Server.

NuGet Downloads License: MIT .NET


Why VQuery?

Most .NET projects end up choosing between hand-written ADO.NET (verbose, repetitive) or a full ORM like EF Core (heavy, opinionated, slow to set up for simple apps). VQuery sits in between:

  • ๐Ÿ”Œ One API, three databases โ€” switch between MySQL, PostgreSQL, and SQL Server without rewriting your data layer
  • โšก Fast โ€” reflection caching means object mapping doesn't slow you down as your app grows
  • ๐Ÿชถ Lightweight โ€” no heavy configuration, no migrations engine, no fighting the framework
  • ๐Ÿงต Async-first โ€” every core operation has an async counterpart
  • ๐Ÿ”’ Safe by default โ€” parameterized queries throughout

If you want Dapper-like simplicity with built-in multi-database support out of the box, VQuery is built for that.

Status: MySQL support is the most tested and battle-tested part of VQuery. PostgreSQL and SQL Server support exist and follow the same API, but have seen less real-world use so far โ€” feedback and bug reports for those are especially welcome.


Installation

dotnet add package VQuery

Or via the Package Manager Console:

Install-Package VQuery

Quick Start

1. Add a connection string to appsettings.json:

{
  "ConnectionStrings": {
    "MYSQLConnection": {
      "server": "127.0.0.1",
      "port": "3306",
      "database": "sampledb",
      "username": "root",
      "password": "123456"
    }
  }
}

2. Query in three lines:

using VQuery;

using var db = new MySQLConnection();
db.ConnectionOpen("MYSQLConnection");

var users = db.Query<User>("SELECT * FROM users");

Swap MySQLConnection for PostgreSQLConnection or SQLServerConnection and everything else stays the same.


Core Features

Feature Description
Query<T>() / QueryAsync<T>() Map query results directly to your model classes
QueryFirst<T>() / QuerySingle<T>() Grab a single record with less boilerplate
QueryFirstOrDefault<T>() / QuerySingleOrDefault<T>() Same as above, but return default instead of throwing when no rows are found
QueryMultiple() Run multiple SELECT statements and get back a DataSet
SelectDataTable() / SelectDataRow() / SelectDataValue() Lower-level access when you don't need object mapping
ExecuteScalar<T>() Return a single value (counts, sums, etc.)
ExecuteNonQuery() Run INSERT/UPDATE/DELETE and get back the affected row count
Execute() / ExecuteRun() Run a statement and get back a bool instead of a row count
Insert() / Update() / Delete() Simple CRUD helpers
Exists() / ExistsAsync() Check whether a query returns any matching rows
Begin() / Commit() / RollBack() Full transaction support
Connection pooling Configurable min/max pool size out of the box
VariableConverter Type-conversion utilities available directly on the connection object

Usage Examples

CRUD

// Insert
db.Insert("users", new Dictionary<string, string>
{
    { "name", "John" },
    { "email", "john@test.com" }
});

// Update
db.Update("users", new Dictionary<string, string>
{
    { "name", "David" }
}, "id=1");

// Delete (parameterized)
db.Delete("DELETE FROM users WHERE id=@id", new() { ["@id"] = 1 });

Note: Insert() and Update() also have overloads that take Dictionary<string, object> instead of Dictionary<string, string>. Prefer the object overloads when your values include numbers, dates, or booleans โ€” the string overloads pass every value through as VARCHAR.

Check existence

bool hasAdmins = db.Exists("SELECT 1 FROM users WHERE role=@role", new() { ["@role"] = "admin" });

bool hasAdminsAsync = await db.ExistsAsync("SELECT 1 FROM users WHERE role=@role", new() { ["@role"] = "admin" });

Transactions

db.Begin();
try
{
    db.Insert("users", new Dictionary<string, string> { { "name", "John" } });
    db.Update("users", new Dictionary<string, string> { { "name", "David" } }, "id=1");
    db.Commit();
}
catch
{
    db.RollBack();
}

Async

var users = await db.QueryAsync<User>("SELECT * FROM users");

var user = await db.QueryFirstAsync<User>(
    "SELECT * FROM users WHERE id=@id",
    new() { ["@id"] = 1 });

Safe single-record lookups

// Returns default(T) instead of throwing when no row is found
var user = db.QueryFirstOrDefault<User>(
    "SELECT * FROM users WHERE id=@id", new() { ["@id"] = 1 });

var userAsync = await db.QueryFirstOrDefaultAsync<User>(
    "SELECT * FROM users WHERE id=@id", new() { ["@id"] = 1 });

QuerySingle<T>() / QuerySingleOrDefault<T>() (and their async versions) work the same way, but throw if more than one row is returned.

VariableConverter utilities

Available directly on the connection object for quick type conversions:

db.ToInt("100");                     // -> 100
db.ToDouble("123.45");               // -> 123.45
db.ToIntString(100);                 // -> "100"
db.ToDoubleString(123.45);           // -> "123.45"
db.ToString(DateTime.Now);           // -> formatted string
db.ToStringDate(DateTime.Now);       // -> "dd-MM-yyyy" by default
db.ToStringDateTime(DateTime.Now);   // -> "dd-MM-yyyy HH:mm:ss" by default
db.ToDate("01-01-2026");             // -> DateTime
db.ToDateTime("01-01-2026 10:00:00");// -> DateTime
db.NumberToText(1000);               // -> number spelled out in words
db.NumberToTextKH(1000);             // -> number spelled out in Khmer
db.NumberToKhNumber(1000);           // -> number in Khmer numerals
db.IsEmpty(row);                     // -> true if a DataRow has no data

Multiple result sets

string sql = @"
    SELECT * FROM users;
    SELECT * FROM roles;
";

DataSet ds = db.QueryMultiple(sql);
DataTable users = ds.Tables[0];
DataTable roles = ds.Tables[1];

Configuration Reference

Each connection block in appsettings.json supports:

Key Description Default
server Host address โ€”
port Port number DB-specific
database Database name โ€”
username / password Credentials โ€”
pooling Enable connection pooling true
minimumPoolSize / maximumPoolSize Pool size range 5 / 100
connectionTimeout Seconds before connection timeout 30
commandTimeout Seconds before command timeout 60
trustServerCertificate SQL Server only false

Supported Frameworks

  • .NET 8.0 (also compatible with .NET 9.0 / 10.0)

Dependencies

  • Microsoft.Data.SqlClient (>= 7.0.1)
  • Microsoft.Extensions.Configuration.Json (>= 8.0.0)
  • MySql.Data (>= 8.4.0)
  • Npgsql (>= 8.0.3)

Contributing

Issues and pull requests are welcome! If you find a bug or have a feature request, please open an issue.

License

MIT โ€” free to use in personal and commercial projects.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  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.0.6 129 7/28/2026
1.0.5 135 6/23/2026