SQLFactory 28.2602.33.95
See the version list below for details.
dotnet add package SQLFactory --version 28.2602.33.95
NuGet\Install-Package SQLFactory -Version 28.2602.33.95
<PackageReference Include="SQLFactory" Version="28.2602.33.95" />
<PackageVersion Include="SQLFactory" Version="28.2602.33.95" />
<PackageReference Include="SQLFactory" />
paket add SQLFactory --version 28.2602.33.95
#r "nuget: SQLFactory, 28.2602.33.95"
#:package SQLFactory@28.2602.33.95
#addin nuget:?package=SQLFactory&version=28.2602.33.95
#tool nuget:?package=SQLFactory&version=28.2602.33.95
SQLFactory
High-performance, lightweight SQL mapper and CRUD helper library for .NET developers
๐ Table of Contents
- Overview
- Features
- Quick Start
- Installation
- Documentation
- Examples
- Building
- Testing
- Contributing
- License
๐ฏ Overview
SQLFactory is a lightweight, high-performance SQL mapping library that provides intuitive CRUD operations and advanced querying capabilities for .NET applications. It bridges the gap between micro-ORMs and full-featured ORMs, offering simplicity without sacrificing control.
Key Highlights
- ๐ High Performance - Minimal overhead with optimized data access patterns
- ๐ง Developer-Friendly - Intuitive API with strong typing and IntelliSense support
- ๐ Cross-Platform - Runs on Windows, Linux, and macOS
- ๐ฆ Lightweight - Small footprint with minimal dependencies
- ๐ฏ Flexible - Works with POCO classes, annotated models, or dynamic queries
- ๐ Production-Ready - Battle-tested with comprehensive unit tests
โจ Features
Core Capabilities
- CRUD Operations - Full Create, Read, Update, Delete support with simple API
- SQL Builder - Fluent interface for building complex SQL queries
- Object Mapping - Automatic mapping between database records and .NET objects
- POCO Support - Work with plain C# classes without attributes
- Annotated Models - Optional attribute-based mapping for fine control
- Dynamic Queries - Build queries dynamically at runtime
- SqlSet - Collection-like access to database tables
- Transaction Support - Built-in transaction management
- Multi-Database - SQL Server, SQLite, and other ADO.NET providers
Eager Loading ๐
- Include() - Load single reference navigation properties (many-to-1, 1-to-1)
- Include() Collections - Load collection navigation properties (1-to-many)
- ThenInclude() - Multi-level nested navigation properties
- Async Eager Loading - Full async/await support with
ToListAsync() - Performance - 99.8% query reduction vs N+1 problem
- Convention-Based - Automatic FK discovery by naming convention
- Split Query Pattern - Avoids cartesian explosion (separate queries for collections)
Query Filters ๐
- Global Filters - Register once, apply everywhere automatically
- Soft Delete -
entity => !entity.IsDeletedapplied to all queries - Multi-Tenancy -
entity => entity.TenantId == currentTenant - Admin Override -
.IgnoreQueryFilters()for special scenarios - Expression-to-SQL - Converts LINQ expressions to SQL WHERE clauses
- Type-Safe - Compile-time checking with full IntelliSense
Technical Features
- โ Nullable reference types enabled
- โ Async/await support throughout
- โ Code analysis and style rules enforced
- โ XML documentation for all public APIs
- โ Source Link support for debugging
- โ Deterministic builds
Advanced Features ๐ All Production Ready
โ Read/Write Splitting (100% complete - NEW!) ๐ฅ
- Horizontal scaling with master-replica configuration
- Automatic query routing - Reads โ replicas, Writes โ primary
- Multiple load balancing strategies - RoundRobin, Random, PrimaryReplica
- Sticky sessions - Read-after-write consistency (configurable window)
- Connection pooling - Max 100 connections per pool, thread-safe
- Explicit routing hints -
UsePrimary(),UseReplica(),UseAutoRouting() - Fluent configuration API -
db.WithReadWriteSplitting(config) - Comprehensive documentation - Setup guides for MySQL, PostgreSQL, SQL Server
- Full example implementations -
samples/ReadWriteSplittingExamples.cs - 17/17 integration tests passing โ
โ Change Tracking (100% complete)
- Full entity state management (Added/Modified/Deleted/Unchanged)
.DetectChanges()with original values snapshot.SaveChanges()batch operation- Relationship fixup and cascade behaviors
- Unit of Work pattern support
- 6/6 integration tests passing โ
โ Fluent Configuration API (100% complete)
ModelBuilderwith fluent entity configurationEntityTypeBuilder<T>andPropertyBuilder<T>for property mapping- Relationship configuration -
HasOne(),HasMany(),WithOne(),WithMany() - Foreign key and principal key configuration
- Delete behaviors: Cascade, SetNull, Restrict, NoAction
- 18/18 relationship tests passing โ
โ Lazy Loading (100% complete - Production Ready)
- Castle.DynamicProxy-based navigation property loading (~600 LOC)
- Automatic FK discovery (3 convention-based strategies)
- Reference and collection navigation support
- Circular reference prevention with max depth tracking
- N+1 query detection with debug warnings
- Per-entity type configuration (EnableFor/DisableFor)
- Include() + Lazy Loading hybrid scenarios tested
- Full documentation (LazyLoading.md)
- 17/17 integration tests passing โ
โ Soft Delete Support (100% complete - Production Ready)
ISoftDeletableinterface with automatic filtering.SoftDelete(),.HardDelete(),.Restore()methods.IncludeDeleted(),.OnlyDeleted()queries- Auto-filter via Query Filters integration
- Full documentation (SoftDelete.md)
- 6/6 integration tests passing โ
โ Code Generation CLI Tool (100% complete)
- System.CommandLine-based modern CLI
- Reverse engineering from SQLite, PostgreSQL, MySQL
- Entity class generation with proper attributes
- Repository pattern scaffolding
- Installable as .NET Global Tool
dotnet tool install --global sqlfactory-codegen
โ Query Result Cache (100% complete)
- In-memory caching with LRU eviction
- Cache key generation from SQL + parameters
.Cacheable(duration)extension method.ClearCache<T>()methods- 17/17 tests passing โ
โ Global Query Filters (100% complete)
- Automatic soft delete, multi-tenancy filtering
- Expression-to-SQL conversion
.IgnoreQueryFilters()for admin scenarios- 6/6 tests passing โ
โ Optimistic Concurrency (100% complete - Production Ready)
[RowVersion]/[Timestamp]attributes โDbConcurrencyExceptionon conflicts โ- Automatic version checking on UPDATE โ
- Provider-specific support (SQL Server, PostgreSQL, MySQL, SQLite) โ
- Conflict resolution strategies documented โ
- Full documentation (OptimisticConcurrency.md)
- 3/3 integration tests passing โ
โ Eager Loading (97.4% complete)
- Include() - Load single reference navigation properties (many-to-1, 1-to-1)
- Include() Collections - Load collection navigation properties (1-to-many)
- ThenInclude() - Multi-level nested navigation properties
- Async Eager Loading - Full async/await support with
ToListAsync() - 34/35 tests passing โ
โ Additional Features
- JSON Columns -
[JsonColumn]attribute with System.Text.Json (100% complete, 3/3 tests โ ) - Upsert Operations -
InsertOrUpdate()for merge operations (100% complete) - Pagination -
ToPagedList()with metadata (8/8 tests โ ) - Dynamic Expression Builder -
Expressionable<T>for fluent conditions (100% complete)
Quality & Testing
- 439/442 tests passing (99.3% pass rate)
- 14/14 advanced features fully production-ready ๐
- Comprehensive integration test coverage
- Production-ready with extensive real-world usage
๐ Quick Start
Installation
dotnet add package SQLFactory
Basic Usage
using AnubisWorks.SQLFactory;
// Connect to database
var db = new Database("YourConnectionString");
// Create a table accessor
var customers = db.GetTable<Customer>();
// Insert
var newCustomer = new Customer
{
Name = "John Doe",
Email = "john@example.com"
};
customers.Insert(newCustomer);
// Query
var customer = customers.FirstOrDefault(c => c.Id == 1);
// Update
customer.Email = "newemail@example.com";
customers.Update(customer);
// Delete
customers.Delete(customer);
๐ฆ Installation
NuGet Package Manager
Install-Package SQLFactory
.NET CLI
dotnet add package SQLFactory
Package Reference
<PackageReference Include="SQLFactory" Version="1.0.0" />
๐ Documentation
Comprehensive documentation is available in the docs directory:
- Getting Started
- API Reference (XML documentation included in package)
- Sample Projects:
- Basic Samples - POCO, Annotated, and Builder patterns
- Real-Life Example - Complete application example
- Database Example - Production-ready scenarios
๐ก Examples
POCO Mapping
public class Customer
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string? Email { get; set; }
}
var db = new Database(connectionString);
var customers = db.GetTable<Customer>();
var allCustomers = customers.ToList();
Annotated Models
[Table("Customers")]
public class Customer
{
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
public int CustomerId { get; set; }
[Column("CustomerName")]
public string Name { get; set; } = string.Empty;
}
SQL Builder
var query = new SqlBuilder()
.Select("c.Id", "c.Name", "o.OrderDate")
.From("Customers c")
.Join("Orders o", "c.Id = o.CustomerId")
.Where("c.Active = @active")
.OrderBy("o.OrderDate DESC");
var results = db.Query<CustomerOrder>(
query.ToString(),
new { active = true }
);
Dynamic Queries
var sqlSet = new SqlSet<Product>(db);
var products = sqlSet
.Where(p => p.Category == "Electronics")
.Where(p => p.Price < 1000)
.OrderBy(p => p.Name)
.Skip(0)
.Take(10)
.ToList();
Eager Loading ๐
using AnubisWorks.SQLFactory.Include;
// Load single reference navigation property
var products = db.Table<Product>()
.Include(p => p.Category)
.ToList();
// Each product.Category is loaded (eliminates N+1 queries)
// Load collection navigation property
var categories = db.Table<Category>()
.Include(c => c.Products)
.ToList();
// Each category.Products contains all related products
// Multi-level nesting with ThenInclude
var products = db.Table<Product>()
.Include(p => p.Category)
.ThenInclude<Product, Category, Region>(c => c.Region)
.ThenInclude<Product, Region, Country>(r => r.Country)
.ToList();
// Product โ Category โ Region โ Country all loaded
// Async eager loading
var products = await db.Table<Product>()
.Include(p => p.Category)
.ThenInclude<Product, Category, Category>(c => c.Parent)
.ToListAsync();
// Combine with queries
var expensiveProducts = db.Table<Product>()
.Where("Price > 1000")
.OrderBy("Name")
.Include(p => p.Category)
.Take(10)
.ToList();
Global Query Filters ๐
// Register a soft delete filter (applies globally)
GlobalFilterManager.Register(new SoftDeleteFilter<Product>());
// Define your filter
public class SoftDeleteFilter<TEntity> : IGlobalFilter<TEntity>
where TEntity : ISoftDeletable
{
public string FilterName => "SoftDelete";
public bool IsEnabled => true;
public Expression<Func<TEntity, bool>> GetFilter() {
return entity => !entity.IsDeleted; // Automatically added to WHERE clause
}
}
// All queries automatically exclude deleted records
var products = db.From<Product>().ToList();
// SELECT * FROM Products WHERE IsDeleted = 0
// Admin view - bypass filters
var allProducts = db.From<Product>()
.IgnoreQueryFilters()
.ToList();
// SELECT * FROM Products (includes deleted)
// Soft delete operation
db.Table<Product>().Extension("SoftDelete").SoftDelete(product);
// UPDATE Products SET IsDeleted = 1 WHERE ProductID = @id
Optimistic Concurrency ๐
public class Product {
public int ProductID { get; set; }
public string ProductName { get; set; }
[RowVersion]
public byte[] RowVersion { get; set; } // Auto-checked on UPDATE
}
// Update with concurrency check
try {
product.ProductName = "Updated Name";
db.Table<Product>().Update(product);
// UPDATE Products SET ... WHERE ProductID = @id AND RowVersion = @rowVersion
} catch (DbConcurrencyException ex) {
// Another user modified the record
Console.WriteLine("Conflict! Reload and merge changes.");
}
Query Result Caching ๐
// Cache for 5 minutes
var products = db.From<Product>()
.Where(p => p.CategoryID == 1)
.Cacheable(TimeSpan.FromMinutes(5))
.ToList();
// First call: hits database
// Subsequent calls within 5min: returns cached result
// Clear cache for entity type
db.Cache.Clear<Product>();
// Clear all cache
db.Cache.ClearAll();
CRUD Interceptors (AOP) ๐
// Define an audit interceptor
public class AuditInterceptor<TEntity> : ICrudInterceptor<TEntity>
where TEntity : IAuditable
{
public string InterceptorName => "Audit";
public int Order => 0;
public void OnInserting(TEntity entity, CrudContext context) {
entity.CreatedAt = DateTime.UtcNow;
entity.CreatedBy = context.CurrentUserId;
}
public void OnUpdating(TEntity entity, CrudContext context) {
entity.UpdatedAt = DateTime.UtcNow;
entity.UpdatedBy = context.CurrentUserId;
}
}
// Register interceptor
InterceptorManager.Register(new AuditInterceptor<Product>());
// All CRUD operations automatically invoke interceptors
db.Table<Product>().Add(product);
// CreatedAt and CreatedBy set automatically before INSERT
Read/Write Splitting ๐ ๐ฅ
using SQLFactory.ReadWriteSplitting;
// Configure master-replica setup
var config = new ReadWriteConfiguration
{
PrimaryConnectionString = "Server=primary;Database=MyDb;...",
ReadReplicaConnectionStrings = new[]
{
"Server=replica1;Database=MyDb;...",
"Server=replica2;Database=MyDb;..."
},
LoadBalancingStrategy = LoadBalancingStrategy.RoundRobin,
UseStickySessions = true,
StickSessionWindowSeconds = 5
};
using (var db = new Database())
{
// Enable Read/Write splitting
db.WithReadWriteSplitting(config);
// Write queries automatically go to PRIMARY
db.Execute("INSERT INTO Users (Name) VALUES (@0)", "John");
// Read queries automatically go to REPLICAS (round-robin)
var users = db.From<User>("SELECT * FROM Users").ToList();
// Force critical read to PRIMARY (most recent data)
var account = db.UsePrimary()
.From<Account>("SELECT * FROM Accounts WHERE Id = @0", 123)
.FirstOrDefault();
// Reset sticky session after transaction
db.ResetStickySession();
}
// Learn more: docs/ReadWriteSplitting.md
๐จ Building
Prerequisites
- .NET 10 SDK or later
- Linux, macOS, or Windows
Build from Source
# Clone the repository
git clone https://github.com/anubisworks/sqlfactory.git
cd sqlfactory
# Restore dependencies
dotnet restore
# Build the solution
dotnet build --configuration Release
# Run tests
dotnet test --configuration Release --collect:"XPlat Code Coverage"
Using Build Scripts
# Full build with versioning
./scripts_dotnet/_buildDotnetSolution.sh
# Build and run tests
./scripts_dotnet/_localTest.sh
# Create NuGet package
dotnet pack --configuration Release
๐งช Testing
SQLFactory includes comprehensive unit and integration tests using NUnit:
# Run all tests
dotnet test
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
# Run specific test category
dotnet test --filter "Category=Integration"
Test Coverage (Production Ready)
- Overall Coverage: 58.83% (steadily improving)
- Core Coverage: 60.21% (main library components)
- Test Count: 392 passing tests (0 failures)
- Framework: NUnit 3.14 with async test support
- Mocking: Moq 4.20 for unit tests
- Databases: SQLite (in-memory) and SQL Server LocalDB
Coverage by Component
| Component | Coverage | Tests | Status |
|---|---|---|---|
| GlobalFilterManager | 97.5% | 18 | โ Production |
| InterceptorManager | 92.5% | 25 | โ Production |
| QueryCache | 80.8% | 17 | โ Production |
| SqlBuilder | 66.0% | 27 | โ Stable |
| SQLFactory Extensions | 63.1% | 33 | โ Stable |
| Query Filters Integration | - | 6 | โ Production |
| Optimistic Concurrency | - | 3 | โ Production |
| Soft Delete | - | 6 | โ Production |
| Include/ThenInclude | - | 15 | โ Production |
| Pagination | - | 8 | โ Production |
๐ ๏ธ Development
Project Structure
sqlfactory/
โโโ Core/ # Main library
โ โโโ SQLFactory.cs # Core database class
โ โโโ SqlBuilder.cs # Query builder
โ โโโ SqlSet.cs # LINQ-like operations
โ โโโ Mapper.cs # Object mapping
โ โโโ Metadata/ # Mapping metadata
โโโ Tests/ # Unit tests
โโโ samples/ # Sample code
โโโ DatabaseRealExample/ # Example application
โโโ RealLifeExample/ # Real-world scenario
โโโ ObjectDumper/ # Utility tool
โโโ docs/ # Documentation
โโโ scripts_dotnet/ # Build scripts
Code Quality
- Nullable reference types enforced
- Code analyzers enabled (Microsoft + StyleCop)
- XML documentation required
- EditorConfig for consistent styling
- Continuous integration ready
๐ค Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Guidelines
- Follow existing code style
- Add unit tests for new features
- Update documentation as needed
- Ensure all tests pass
- Maintain or improve code coverage
๐ License
This project is licensed under the GNU Lesser General Public License v3.0 or later (LGPL-3.0-or-later).
See LICENSE file for details.
What this means:
- โ Use in commercial applications
- โ Modify the library
- โ Distribute modifications
- โ Private use
- โ ๏ธ Disclose source if you modify SQLFactory itself
- โ ๏ธ Use same license for SQLFactory modifications
- โ Your application can use any license
๐ Support
- ๐ Issue Tracker
- ๐ง Email: support@anubisworks.com
- ๐ Documentation
๐ Acknowledgments
- Built with โค๏ธ by Michael Agata and contributors
- Inspired by Dapper, LINQ to SQL, and Entity Framework
- Community feedback and contributions
Made with โค๏ธ by AnubisWorks
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 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. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Castle.Core (>= 5.1.1)
- Microsoft.Data.SqlClient (>= 5.2.2)
- Npgsql (>= 6.0.11)
- System.Text.Json (>= 9.0.0)
-
net10.0
- Castle.Core (>= 5.1.1)
- Microsoft.Data.SqlClient (>= 5.2.2)
- Npgsql (>= 6.0.11)
-
net8.0
- Castle.Core (>= 5.1.1)
- Microsoft.Data.SqlClient (>= 5.2.2)
- Npgsql (>= 6.0.11)
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 |
|---|---|---|
| 28.2602.50.115 | 94 | 2/19/2026 |
| 28.2602.33.113 | 103 | 2/2/2026 |
| 28.2602.33.95 | 102 | 2/2/2026 |
| 2.2405.143.35 | 131 | 5/22/2024 |
| 2.2209.244.34 | 142 | 2/1/2023 |
| 2.2208.230.33 | 140 | 8/18/2022 |
| 2.2207.208.32 | 152 | 7/26/2022 |
| 2.2207.208.31 | 161 | 7/26/2022 |
| 2.32.353.20 | 305 | 12/18/2020 |
| 2.32.84.29 | 182 | 3/25/2022 |
| 2.0.0 | 105 | 2/1/2026 |