MJCZone.DapperMatic
0.0.15
See the version list below for details.
dotnet add package MJCZone.DapperMatic --version 0.0.15
NuGet\Install-Package MJCZone.DapperMatic -Version 0.0.15
<PackageReference Include="MJCZone.DapperMatic" Version="0.0.15" />
<PackageVersion Include="MJCZone.DapperMatic" Version="0.0.15" />
<PackageReference Include="MJCZone.DapperMatic" />
paket add MJCZone.DapperMatic --version 0.0.15
#r "nuget: MJCZone.DapperMatic, 0.0.15"
#:package MJCZone.DapperMatic@0.0.15
#addin nuget:?package=MJCZone.DapperMatic&version=0.0.15
#tool nuget:?package=MJCZone.DapperMatic&version=0.0.15
MJCZone.DapperMatic
Model-first database schema management for .NET - Create, modify, and manage database schemas using strongly-typed C# models across SQL Server, MySQL, PostgreSQL, and SQLite.
DapperMatic extends IDbConnection with intuitive extension methods for DDL (Data Definition Language) operations. Define your database schema in code and let DapperMatic handle the provider-specific SQL generation and execution.
โจ Key Features
- ๐ฏ Model-First Approach - Define schemas using strongly-typed C# classes (
DmTable,DmColumn, etc.) - ๐ Data Annotations Support - Use familiar
[Table],[Key]attributes or advanced[DmColumn]attributes - ๐ Cross-Database Support - SQL Server, MySQL/MariaDB, PostgreSQL, SQLite with consistent API
- ๐ Schema Reverse Engineering - Extract complete database schemas including tables, views, constraints, and indexes
- ๐ก๏ธ SQL Injection Protected - Comprehensive validation prevents malicious SQL injection attacks
- โก Dapper Integration - Built on top of Dapper for high-performance data access
- ๐งช Extensively Tested - 500+ tests covering all providers and edge cases
- ๐ฆ Zero Configuration - Works out-of-the-box with your existing Dapper applications
๐ Quick Start
Installation
dotnet add package MJCZone.DapperMatic
Basic Usage
using MJCZone.DapperMatic;
using MJCZone.DapperMatic.Models;
using System.Data.SqlClient;
// Connect to your database (works with any IDbConnection)
using var connection = new SqlConnection("your-connection-string");
await connection.OpenAsync();
// Define a table model
var usersTable = new DmTable("dbo", "Users", new[]
{
new DmColumn("Id", typeof(int), isPrimaryKey: true, isAutoIncrement: true),
new DmColumn("Name", typeof(string), length: 100, isNullable: false),
new DmColumn("Email", typeof(string), length: 255, isUnique: true),
new DmColumn("CreatedAt", typeof(DateTime), defaultExpression: "GETDATE()")
});
// Create the table if it doesn't exist
bool created = await connection.CreateTableIfNotExistsAsync(usersTable);
// Check if table exists
bool exists = await connection.DoesTableExistAsync("dbo", "Users");
// Add a new column
await connection.CreateColumnIfNotExistsAsync("dbo", "Users",
new DmColumn("LastLoginAt", typeof(DateTime?), isNullable: true));
// Create an index
await connection.CreateIndexIfNotExistsAsync("dbo", "Users", "IX_Users_Email",
new[] { "Email" });
Data Annotations Approach
DapperMatic supports both standard .NET data annotations and its own comprehensive attribute system:
using MJCZone.DapperMatic.DataAnnotations;
using MJCZone.DapperMatic.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
// Using standard .NET attributes
[Table("Users", Schema = "dbo")]
public class User
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; } = null!;
[EmailAddress]
public string Email { get; set; } = null!;
}
// Using DapperMatic-specific attributes for advanced features
[DmTable("dbo", "Products")]
[DmIndex("IX_Products_Name", new[] { nameof(Name) }, isUnique: true)]
public class Product
{
[DmColumn(isPrimaryKey: true, isAutoIncrement: true)]
public int Id { get; set; }
[DmColumn("product_name", length: 255, isNullable: false)]
public string Name { get; set; } = null!;
[DmColumn("price", precision: 10, scale: 2,
checkExpression: "Price > 0",
defaultExpression: "0.00")]
public decimal Price { get; set; }
[DmColumn(isForeignKey: true, referencedTableName: "Categories",
referencedColumnName: "Id", onDelete: DmForeignKeyAction.Cascade)]
public int CategoryId { get; set; }
[DmColumn(defaultExpression: "GETDATE()")]
public DateTime CreatedAt { get; set; }
}
// Generate table from class and create it
var productTable = DmTableFactory.GetTable<Product>();
await connection.CreateTableIfNotExistsAsync(productTable);
// Or use the type directly
var userTable = DmTableFactory.GetTable(typeof(User));
await connection.CreateTableIfNotExistsAsync(userTable);
Schema Management
// Create schema if it doesn't exist
await connection.CreateSchemaIfNotExistsAsync("app");
// Work with views
await connection.CreateViewIfNotExistsAsync("dbo", "ActiveUsers",
"SELECT * FROM Users WHERE LastLoginAt > DATEADD(day, -30, GETDATE())");
// Manage constraints
await connection.CreateCheckConstraintIfNotExistsAsync("dbo", "Users", "Email",
"chk_email_format", "Email LIKE '%@%.%'");
await connection.CreateForeignKeyConstraintIfNotExistsAsync("dbo", "Orders",
"FK_Orders_Users", new[] { "UserId" }, "dbo", "Users", new[] { "Id" });
Schema Reverse Engineering
DapperMatic provides comprehensive capabilities to extract and analyze existing database schemas. This is essential for tools that need to understand current database structure, perform schema comparisons, or generate code from existing databases.
// Extract complete table definition with all metadata
var existingTable = await connection.GetTableAsync("dbo", "Users");
if (existingTable != null)
{
Console.WriteLine($"Table: {existingTable.SchemaName}.{existingTable.TableName}");
// Access all columns with detailed metadata
foreach (var column in existingTable.Columns)
{
Console.WriteLine($" {column.ColumnName}: {column.DotnetType}");
Console.WriteLine($" Nullable: {column.IsNullable}");
Console.WriteLine($" Primary Key: {column.IsPrimaryKey}");
Console.WriteLine($" Auto Increment: {column.IsAutoIncrement}");
Console.WriteLine($" Unique: {column.IsUnique}");
if (column.IsForeignKey)
{
Console.WriteLine($" References: {column.ReferencedTableName}.{column.ReferencedColumnName}");
}
}
// Access constraints
if (existingTable.PrimaryKeyConstraint != null)
{
var pkColumns = string.Join(", ", existingTable.PrimaryKeyConstraint.Columns.Select(c => c.ColumnName));
Console.WriteLine($" Primary Key: {pkColumns}");
}
// Access foreign key constraints
foreach (var fk in existingTable.ForeignKeyConstraints)
{
Console.WriteLine($" FK {fk.ConstraintName}: {string.Join(", ", fk.Columns.Select(c => c.ColumnName))} -> {fk.ReferencedSchemaName}.{fk.ReferencedTableName}");
}
// Access indexes
foreach (var index in existingTable.Indexes)
{
var indexColumns = string.Join(", ", index.Columns.Select(c => $"{c.ColumnName} {(c.IsDescending ? "DESC" : "ASC")}"));
Console.WriteLine($" Index {index.IndexName}: {indexColumns} (Unique: {index.IsUnique})");
}
}
// Get all tables in a schema
var allTables = await connection.GetTablesAsync("dbo");
Console.WriteLine($"Found {allTables.Count} tables in schema 'dbo'");
// Get table names only (lightweight operation)
var tableNames = await connection.GetTableNamesAsync("dbo");
foreach (var tableName in tableNames)
{
Console.WriteLine($"Table: {tableName}");
}
// Extract view definitions
var salesView = await connection.GetViewAsync("dbo", "MonthlySales");
if (salesView != null)
{
Console.WriteLine($"View Definition:\n{salesView.Definition}");
}
// Get all views
var allViews = await connection.GetViewsAsync("dbo");
// Extract individual column metadata
var emailColumn = await connection.GetColumnAsync("dbo", "Users", "Email");
if (emailColumn != null)
{
Console.WriteLine($"Email column type: {emailColumn.DotnetType}");
Console.WriteLine($"Max length: {emailColumn.Length}");
Console.WriteLine($"Is unique: {emailColumn.IsUnique}");
}
// Get all columns for a table
var userColumns = await connection.GetColumnsAsync("dbo", "Users");
// Extract constraint information
var foreignKeys = await connection.GetForeignKeyConstraintsAsync("dbo", "Orders");
var checkConstraints = await connection.GetCheckConstraintsAsync("dbo", "Users");
var uniqueConstraints = await connection.GetUniqueConstraintsAsync("dbo", "Products");
// Get index information
var userIndexes = await connection.GetIndexesAsync("dbo", "Users");
var emailIndex = await connection.GetIndexAsync("dbo", "Users", "IX_Users_Email");
// List all schemas in the database
var schemas = await connection.GetSchemaNamesAsync();
Console.WriteLine($"Available schemas: {string.Join(", ", schemas)}");
// Generate C# class from existing table
var existingUsersTable = await connection.GetTableAsync("dbo", "Users");
if (existingUsersTable != null)
{
// You can use the table definition to generate corresponding C# classes
// or compare with your model definitions for schema validation
var modelTable = DmTableFactory.GetTable<User>();
// Compare existingUsersTable with modelTable for differences
}
๐๏ธ Supported Database Providers
| Provider | Versions Tested | Connection Type | Notes |
|---|---|---|---|
| SQL Server | 2017, 2019, 2022 | SqlConnection |
Full feature support |
| MySQL | 8.0, 8.1 | MySqlConnection |
Includes MariaDB compatibility |
| PostgreSQL | 13, 14, 15, 16 | NpgsqlConnection |
PostGIS extensions supported |
| SQLite | 3.x | SQLiteConnection |
File-based and in-memory |
๐ฏ Core Capabilities
Database Discovery & Reverse Engineering
- โ Extract complete table definitions with all metadata
- โ Retrieve individual columns, constraints, indexes, and relationships
- โ Discover and analyze view definitions and SQL
- โ Enumerate all database schemas and objects
- โ Query existing database structure across all providers
- โ Generate C# models from existing database tables
- โ Provider-specific metadata extraction (auto-increment detection, data types, etc.)
Schema Operations
- โ Create and manage database schemas
- โ Cross-schema operations
- โ Provider compatibility handling
- โ Schema existence checking
Table Operations
- โ Create, drop, rename, and modify tables
- โ Check table existence and retrieve metadata
- โ Support for temporary tables
- โ Truncate tables with data preservation options
Column Management
- โ Add, drop, rename, and modify columns
- โ Full data type mapping across providers
- โ Auto-increment and computed columns
- โ Default values and nullable constraints
Constraint Support
- โ Primary keys (single and composite)
- โ Foreign keys with cascade options
- โ Unique constraints
- โ Check constraints with expression validation
- โ Default constraints
Index Management
- โ Create and drop indexes
- โ Unique and composite indexes
- โ Provider-specific optimizations
View Operations
- โ Create, drop, and manage views
- โ Secure view definition validation
๐ง Advanced Features
Type Mapping
DapperMatic automatically maps .NET types to appropriate SQL types for each database provider:
// Automatic type mapping
new DmColumn("Price", typeof(decimal), precision: 10, scale: 2)
// โ SQL Server: decimal(10,2)
// โ MySQL: decimal(10,2)
// โ PostgreSQL: numeric(10,2)
// โ SQLite: real
new DmColumn("Tags", typeof(string[])) // PostgreSQL arrays
new DmColumn("Config", typeof(object)) // JSON columns where supported
Provider Detection
// Automatic provider detection
bool supportsSchemas = connection.SupportsSchemas();
var version = await connection.GetDatabaseVersionAsync();
Security Features
- SQL Injection Protection - All user inputs are validated and sanitized
- Expression Validation - Check constraints and view definitions are secured
- Identifier Normalization - Table/column names are properly escaped
๐ Comparison with Alternatives
| Feature | DapperMatic | Entity Framework Core | FluentMigrator |
|---|---|---|---|
| Model-First | โ Code-first schemas | โ Code-first entities | โ Migration-based |
| Data Annotations | โ Standard + Advanced | โ Standard annotations | โ Fluent API only |
| Cross-Database | โ 4 providers | โ Many providers | โ Many providers |
| Performance | โก Dapper-based | ๐ ORM overhead | โก Direct SQL |
| Learning Curve | ๐ข Minimal | ๐ก Moderate | ๐ก Moderate |
| Schema Focus | โ DDL operations | โ Entity operations | โ Migration scripts |
| Runtime Schema Changes | โ Dynamic | โ Requires migrations | โ Requires migrations |
| Reverse Engineering | โ Full schema extraction | โ Scaffold from database | โ No reverse engineering |
| Size | ๐ฆ Lightweight | ๐ฆ Full framework | ๐ฆ Migration-focused |
When to Choose DapperMatic
โ Perfect for:
- Applications that need dynamic schema management
- Dapper-based applications requiring DDL operations
- Multi-tenant applications with varying schemas
- Tools that generate database schemas from models
- APIs that manage database structures programmatically
- Schema analysis and documentation tools
- Database migration and comparison utilities
- Code generators that create models from existing databases
- Developers who prefer data annotations over fluent APIs
โ Consider alternatives for:
- Full ORM functionality (use Entity Framework Core)
- Complex migration workflows (use FluentMigrator)
- Applications that rarely modify schema structure
๐ Dependencies
This library requires .NET 8.0 or later and uses Dapper for data access operations. We use a version range ([2.1.35,3.0.0)) to ensure compatibility with your application's Dapper version while maintaining functionality.
Framework Requirements: .NET 8.0+ (compatible with .NET 8 and .NET 9 applications)
Supported Dapper Versions: 2.1.35 through 2.1.66+ (any 2.1.x version)
Version Conflict Resolution: If your application uses a different Dapper 2.1.x version, NuGet will automatically resolve to your version, preventing conflicts.
๐ Documentation
- Full Documentation: mjczone.github.io/MJCZone.DapperMatic
- API Reference: Complete method documentation with examples
- Provider Guides: Database-specific tips and best practices
- Migration Examples: Real-world usage scenarios
๐ค Contributing
We welcome contributions! Please see our Contributing Guidelines for details on:
- ๐ Reporting bugs
- ๐ก Suggesting features
- ๐ง Submitting pull requests
- ๐งช Adding tests for new providers
๐๏ธ Project Status
- Stability: Pre-Release Stable
- Maintenance: Actively maintained
- Testing: 500+ automated tests across all providers
- Security: SQL injection protected with comprehensive validation
- Performance: Optimized for high-throughput scenarios
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
โญ Star this repository if you find DapperMatic helpful for your projects!
| Product | Versions 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. |
-
net8.0
- Dapper (>= 2.1.35 && < 3.0.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on MJCZone.DapperMatic:
| Package | Downloads |
|---|---|
|
MJCZone.DapperMatic.AspNetCore
Provides ASP.NET Core Web API endpoints and middleware for database schema management using DapperMatic. Includes endpoints for tables, columns, indexes, constraints, and views across SQL Server, MySQL/MariaDB, PostgreSQL, and SQLite. |
|
|
MJCZone.MediaMatic.AspNetCore
ASP.NET Core integration for MediaMatic with browser-aware optimization and minimal API endpoints |
GitHub repositories
This package is not used by any popular GitHub repositories.