Visor.SqlServer
1.1.0
See the version list below for details.
dotnet add package Visor.SqlServer --version 1.1.0
NuGet\Install-Package Visor.SqlServer -Version 1.1.0
<PackageReference Include="Visor.SqlServer" Version="1.1.0" />
<PackageVersion Include="Visor.SqlServer" Version="1.1.0" />
<PackageReference Include="Visor.SqlServer" />
paket add Visor.SqlServer --version 1.1.0
#r "nuget: Visor.SqlServer, 1.1.0"
#:package Visor.SqlServer@1.1.0
#addin nuget:?package=Visor.SqlServer&version=1.1.0
#tool nuget:?package=Visor.SqlServer&version=1.1.0
Visor
High-performance, Source-Generated ORM for .NET 10+. Treats your Database Stored Procedures as a strictly typed API.
Visor is designed to solve the "Enterprise Gap" in .NET data access:
- Dapper is fast but type-unsafe and requires boilerplate.
- EF Core is convenient but heavy and slow for bulk operations.
- Visor uses Source Generators to write zero-allocation ADO.NET code for you at compile time. Visor automates TVP boilerplate that you usually write manually.
π Benchmarks: The "10k Insert" Challenge
We compared inserting 10,000 records into MS SQL Server using a Transactional Stored Procedure with Table-Valued Parameters (TVP).
| Method | Operation | Time (Mean) | Memory Allocated | GC Gen0/1/2 |
|---|---|---|---|---|
| Visor (TVP) | Streaming | 51.82 ms | 1.07 MB | 0 / 0 / 0 |
| EF Core 10 | Bulk Insert | 517.73 ms | 65.04 MB | 8 / 3 / 1 |
| Dapper | Loop Insert | 43,069.73 ms | 15.34 MB | 1 / 0 / 0 |
Why is Visor 10x faster than EF and 800x faster than loops?
- Zero Allocation Streaming: Visor maps
List<T>directly toIEnumerable<SqlDataRecord>(MSSQL) or Arrays (Postgres) usingyield return. No intermediateDataTableor memory copying. - No Runtime Reflection: All mapping code is generated at compile-time.
- Strict Mapping: If your DB schema changes, Visor fails fast with clear exceptions, not silent data corruption.
π¦ Installation
dotnet add package Visor.Core
dotnet add package Visor.Generators
# Choose your provider:
dotnet add package Visor.SqlServer
# OR
dotnet add package Visor.PostgreSql
β‘ Quick Start (MSSQL)
1. Define your Data Contract
Describe your Stored Procedure as a C# interface.
using Visor.Abstractions;
[Visor(VisorProvider.SqlServer)]
public interface IUserRepository
{
// 1. Simple Execute (Scalar)
[Endpoint("sp_GetUserCount")]
Task<int> GetCountAsync();
// 2. Read Data (DTO Mapping)
[Endpoint("sp_GetUserById")]
Task<UserDto> GetUserAsync(int id);
// 3. High-Performance Bulk Insert (TVP)
[Endpoint("sp_ImportUsers")]
Task ImportUsersAsync(List<UserItemDto> users);
}
2. Define your DTOs
Use [VisorMsSqlColumn] for strict SQL type mapping.
using Visor.SqlServer; // Provider-specific attributes
[VisorTable("dbo.UserListType")] // Matches SQL User-Defined Type
public class UserItemDto
{
[VisorMsSqlColumn(0, System.Data.SqlDbType.Int)]
public int Id { get; set; }
[VisorMsSqlColumn(1, System.Data.SqlDbType.NVarChar, 100)]
public string Name { get; set; }
}
3. Register & Use
Visor generates the implementation class UserRepository automatically.
// In Program.cs
services.AddScoped<IVisorConnectionFactory>(sp =>
new SqlServerConnectionFactory("Server=..."));
services.AddScoped<IUserRepository, UserRepository>();
// In your Service
public class MyService(IUserRepository repo)
{
public async Task SyncUsers(List<UserItemDto> users)
{
// This executes with Zero Allocation!
await repo.ImportUsersAsync(users);
}
}
π PostgreSQL Support
Visor fully supports PostgreSQL via Npgsql. It maps List<T> parameters to PostgreSQL Arrays/Composite Types automatically.
1. Define Interface
Specify the provider in the attribute:
[Visor(VisorProvider.PostgreSql)] // <--- Switch to Postgres
public interface IPgUserRepo
{
[Endpoint("sp_import_users")]
Task ImportUsersAsync(List<PgUserItem> users);
}
2. Configure Bootstrapper (Important!)
PostgreSQL requires composite types to be registered at startup. Visor generates a helper method for this.
// In Program.cs
var dataSourceBuilder = new NpgsqlDataSourceBuilder("Host=...");
// This method is AUTO-GENERATED by Visor!
// It registers all types marked with [VisorTable].
dataSourceBuilder.UseVisor();
var dataSource = dataSourceBuilder.Build();
services.AddScoped<IVisorConnectionFactory>(sp =>
new PostgreSqlConnectionFactory(dataSource));
3. Define DTO
Use [VisorColumn] with Name property to map C# PascalCase to Postgres snake_case. Types are inferred automatically.
[VisorTable("user_list_type")]
public class PgUserItem
{
[VisorColumn(0, Name = "id")]
public int Id { get; set; }
[VisorColumn(1, Name = "user_name")]
public string UserName { get; set; }
}
π‘οΈ Transaction Support
Visor supports explicit transactions via the VisorDbLease pattern (Unit of Work).
public async Task CreateOrderFlow(OrderDto order)
{
// Start a transaction scope (scoped per request)
await _factory.BeginTransactionAsync();
try
{
// These repositories will automatically share the active transaction
await _orders.CreateAsync(order);
await _inventory.DecreaseStockAsync(order.ProductId, order.Quantity);
await _factory.CommitTransactionAsync();
}
catch
{
await _factory.RollbackTransactionAsync();
throw;
}
}
π§ Philosophy: The "White Box" Approach
Most ORMs are "Black Boxes" β they do magic at runtime that you can't see or debug easily. Visor is a "White Box".
- It generates readable C# code in your
obj/Generatedfolder. - You can step through the generated code with a debugger.
- You can see exactly how
SqlDataReaderorNpgsqlDataReaderis being read. - Strict by Default: If a column is missing in the result set, Visor throws a
VisorMappingExceptionimmediately, preventing "silent zero" bugs in production.
πΊοΈ Roadmap
- MSSQL Support (Complete)
- TVP Streaming (Complete)
- PostgreSQL Support (Complete)
- Transactions (Complete)
- NuGet Packaging
- CLI Tool for Database-First scaffolding
License
Distributed under the MIT License. See LICENSE for more information.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Microsoft.Data.SqlClient (>= 6.1.3)
- Visor.Core (>= 1.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.