CG.Infrastructure.Data
3.10.9
dotnet add package CG.Infrastructure.Data --version 3.10.9
NuGet\Install-Package CG.Infrastructure.Data -Version 3.10.9
<PackageReference Include="CG.Infrastructure.Data" Version="3.10.9" />
<PackageVersion Include="CG.Infrastructure.Data" Version="3.10.9" />
<PackageReference Include="CG.Infrastructure.Data" />
paket add CG.Infrastructure.Data --version 3.10.9
#r "nuget: CG.Infrastructure.Data, 3.10.9"
#:package CG.Infrastructure.Data@3.10.9
#addin nuget:?package=CG.Infrastructure.Data&version=3.10.9
#tool nuget:?package=CG.Infrastructure.Data&version=3.10.9
CG.Infrastructure.Data
A comprehensive data access library that provides database migration, data access patterns, and repository interfaces using DbUp and Dapper for .NET applications.
Overview
CG.Infrastructure.Data is a specialized library that provides robust data access capabilities, database migration management, and repository pattern interfaces. It leverages DbUp for database schema management and Dapper for high-performance data access, offering a foundation for data persistence in .NET applications.
Note: This library provides interfaces and infrastructure components. Concrete implementations of repositories, database seeding, and connection management must be provided by consuming applications.
Features
- Database Migration Management: Automated database schema updates using DbUp
- High-Performance Data Access: Lightweight ORM capabilities with Dapper
- Repository Pattern Interfaces: Generic repository interface for common CRUD operations
- Transaction Support: Full transaction management with rollback capabilities
- Connection Management: Flexible connection string handling with named connections
- Database Creation: Automatic database creation and configuration
- Script Management: Multiple script source options (file system, assemblies, etc.)
- Environment Awareness: Docker and local environment support
- Pagination Support: Built-in pagination with customizable query generation
- Column Protection: SQL injection protection for column names
- Service Registration: Automatic service registration with dependency injection
Requirements
- .NET 9.0 or later
- CG.Infrastructure.Core 3.10.8+
- CG.Infrastructure.Configuration 3.10.1+
- Dapper 2.1.66+
- dbup-core 6.0.4+
- dbup-sqlserver 6.0.0+
- Microsoft.Data.SqlClient 6.1.1+
- Microsoft.Extensions.Configuration.Abstractions 9.0.8+
- Microsoft.Extensions.DependencyInjection.Abstractions 9.0.8+
- Microsoft.Extensions.Logging.Abstractions 9.0.8+
Installation
dotnet add package CG.Infrastructure.Data
Or add the following to your .csproj
file:
<PackageReference Include="CG.Infrastructure.Data" Version="3.10.8" />
Quick Start
1. Configure Database Settings
Add configuration to your appsettings.json
:
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MyApp;Trusted_Connection=true;",
"ReadOnlyConnection": "Server=localhost;Database=MyAppReadOnly;Trusted_Connection=true;"
},
"DbUpOptions": {
"UseDocker": false,
"DbSchema": "dbo",
"Drop": false,
"Ensure": true,
"Journal": "__SchemaVersions",
"ScriptPath": "C:\\Scripts\\Database",
"UseLocal": false,
"DbPath": "C:\\Databases",
"DbInitialSize": "10MB",
"DbMaxSize": "100MB",
"DbFileGrowth": "10MB"
},
"DbOptions": {
"CommandTimeout": 3000,
"GetLastInsertId": "SELECT @@IDENTITY;"
}
}
2. Register Data Services
In your Program.cs
or Startup.cs
:
using Infrastructure.Data.Extensions;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Register data services
builder.Services.RegisterInfraDataServices(builder.Configuration);
var app = builder.Build();
3. Use Data Access Services
[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
private readonly IDataAccess _dataAccess;
public UsersController(IDataAccess dataAccess)
{
_dataAccess = dataAccess;
}
[HttpGet("custom")]
public async Task<ActionResult<IEnumerable<User>>> GetUsersCustom()
{
var query = "SELECT * FROM Users WHERE IsActive = @IsActive";
var parameters = new { IsActive = true };
var users = await _dataAccess.LoadData<User, object>(
query, parameters, "DefaultConnection");
return Ok(users);
}
}
Core Functionality
Database Migration with DbUp
The library provides comprehensive database migration capabilities:
// Get migration service
var migrationService = serviceProvider.GetRequiredService<IDbMigrationService>();
// Configure scripts to run
var scripts = new List<ScriptConfig>
{
new ScriptConfig
{
Folder = "Initial",
Scripts = ScriptEnum.FileSystem,
AlwaysRun = true
},
new ScriptConfig
{
Folder = "Updates",
Scripts = ScriptEnum.ExecutingAssembly,
AlwaysRun = false
}
};
// Run migrations
var success = migrationService.UpgradeDatabase(scripts);
Data Access with Dapper
Direct SQL execution with full transaction support:
// Load data
var users = await _dataAccess.LoadData<User, object>(
"SELECT * FROM Users WHERE Department = @Department",
new { Department = "IT" },
"DefaultConnection"
);
// Load single record
var user = await _dataAccess.LoadSingle<User, object>(
"SELECT * FROM Users WHERE Id = @Id",
new { Id = 1 },
"DefaultConnection"
);
// Execute commands
var affectedRows = await _dataAccess.SaveData(
"INSERT INTO Users (Name, Email) VALUES (@Name, @Email)",
new { Name = "John Doe", Email = "john@example.com" },
"DefaultConnection"
);
// Get scalar values
var userId = await _dataAccess.SaveScalar(
"INSERT INTO Users (Name, Email) VALUES (@Name, @Email); SELECT @@IDENTITY;",
new { Name = "Jane Doe", Email = "jane@example.com" },
"DefaultConnection"
);
Transaction Management
Full transaction support for complex operations:
// Start transaction
using var transaction = _dataAccess.StartTransaction("DefaultConnection");
try
{
// Execute multiple operations in transaction
var userResult = await _dataAccess.SaveDataInTransaction(
"INSERT INTO Users (Name, Email) VALUES (@Name, @Email)",
new { Name = "John Doe", Email = "john@example.com" },
transaction
);
var profileResult = await _dataAccess.SaveDataInTransaction(
"INSERT INTO UserProfiles (UserId, Bio) VALUES (@UserId, @Bio)",
new { UserId = userResult, Bio = "Software Developer" },
transaction
);
// Commit transaction
_dataAccess.CommitTransaction(transaction);
}
catch
{
// Rollback on error
_dataAccess.RollbackTransaction(transaction);
throw;
}
Repository Pattern Interface
The library provides the IRepository<T>
interface. You must implement concrete repository classes:
// Example implementation - you must create this class
public class UserRepository : IRepository<User>
{
private readonly IDataAccess _dataAccess;
public UserRepository(IDataAccess dataAccess)
{
_dataAccess = dataAccess;
}
public async Task<IEnumerable<User>> GetAllAsync()
{
return await _dataAccess.LoadData<User, object>(
"SELECT * FROM Users", null, "DefaultConnection");
}
public async Task<User?> GetByIdAsync(object id)
{
return await _dataAccess.LoadSingle<User, object>(
"SELECT * FROM Users WHERE Id = @Id",
new { Id = id },
"DefaultConnection"
);
}
public async Task<Guid> CreateAsync(User entity)
{
var result = await _dataAccess.SaveScalar(
"INSERT INTO Users (Name, Email) VALUES (@Name, @Email); SELECT @@IDENTITY;",
entity,
"DefaultConnection"
);
return new Guid(result.ToString());
}
public async Task<bool> UpdateAsync(User entity)
{
var affected = await _dataAccess.SaveData(
"UPDATE Users SET Name = @Name, Email = @Email WHERE Id = @Id",
entity,
"DefaultConnection"
);
return affected > 0;
}
public async Task<bool> DeleteByIdAsync(object id)
{
var affected = await _dataAccess.SaveData(
"DELETE FROM Users WHERE Id = @Id",
new { Id = id },
"DefaultConnection"
);
return affected > 0;
}
// Implement other interface methods...
public async Task<IEnumerable<User>> FindAsync(Expression<Func<User, bool>> predicate)
{
// Implementation depends on your requirements
throw new NotImplementedException("Implement based on your needs");
}
public async Task<bool> ExistsAsync(Expression<Func<User, bool>> predicate)
{
// Implementation depends on your requirements
throw new NotImplementedException("Implement based on your needs");
}
public async Task<bool> DeleteAsync(User entity)
{
return await DeleteByIdAsync(entity.Id);
}
}
Pagination Support
Built-in pagination with customizable query generation:
// Configure pagination options
services.RegisterDbOptions(configuration, options =>
{
options.GetPageQuery = (input, pageIndex, pageSize, totalCount, orderBy, pairs) =>
{
var offset = (pageIndex - 1) * pageSize;
return $"{input} {orderBy} OFFSET {offset} ROWS FETCH NEXT {pageSize} ROWS ONLY";
};
});
// Use pagination
public async Task<PagedResult<User>> GetUsersPaged(int page, int pageSize)
{
var offset = (page - 1) * pageSize;
var users = await _dataAccess.LoadData<User, object>(
"SELECT * FROM Users ORDER BY Name OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY",
new { Offset = offset, PageSize = pageSize },
"DefaultConnection"
);
var totalCount = await _dataAccess.LoadSingle<int, object>(
"SELECT COUNT(*) FROM Users",
null,
"DefaultConnection"
);
return new PagedResult<User>(users, totalCount, page, pageSize);
}
Configuration Options
DbUpOptions
Property | Description | Default |
---|---|---|
UseDocker |
Flag indicating Docker environment | false |
DbSchema |
Database schema name | "dbo" |
Drop |
Whether to drop existing database | false |
Ensure |
Whether to ensure database exists | false |
Journal |
Schema version table name | "__SchemaVersions" |
ScriptPath |
Path to script files | null |
Collate |
Database collation | "SQL_Latin1_General_CP1_CI_AS" |
UseLocal |
Use local database configuration | false |
DbPath |
Local database file path | null |
DbInitialSize |
Initial database size | null |
DbMaxSize |
Maximum database size | null |
DbFileGrowth |
Database file growth size | null |
LogPath |
Log file path | null |
LogInitialSize |
Initial log size | null |
LogMaxSize |
Maximum log size | null |
LogFileGrowth |
Log file growth size | null |
DbOptions
Property | Description | Default |
---|---|---|
ColumnProtect |
Column name protection dictionary | {"left": "[", "right": "]"} |
GetPageQuery |
Custom pagination query function | Built-in SQL Server pagination |
CommandTimeout |
SQL command timeout in milliseconds | 3000 |
GetLastInsertId |
Query to get last insert ID | "SELECT @@IDENTITY;" |
EnableRetryOnFailure |
Enable retry policy for failed operations | false |
MaxRetryCount |
Maximum number of retry attempts | 3 |
RetryInterval |
Retry interval in seconds | 5 |
Script Management
The library supports multiple script sources through ScriptEnum
:
- FileSystem: Scripts from file system paths
- ExecutingAssembly: Scripts embedded in executing assembly
- EntryAssembly: Scripts embedded in entry assembly
- SpecificAssembly: Scripts from a specific assembly
- ExecutingAssemblies: Scripts from multiple executing assemblies
Script Configuration
var scripts = new List<ScriptConfig>
{
new ScriptConfig
{
Folder = "Initial",
Scripts = ScriptEnum.FileSystem,
AlwaysRun = true,
Assembly = null
},
new ScriptConfig
{
Folder = "Migrations",
Scripts = ScriptEnum.ExecutingAssembly,
AlwaysRun = false,
Assembly = "MyApp.Data"
}
};
Service Registration
The library provides extension methods for easy service registration:
RegisterInfraDataServices
Registers all data services with configuration:
services.RegisterInfraDataServices(configuration);
This method:
- Registers
DbUpOptions
with configuration binding - Registers
DbOptions
with configuration binding - Registers repository interfaces (note: implementations must be provided separately)
- Registers data access services
- Registers migration services
Important: Repository implementations are not automatically registered. You must register them manually or implement the RegisterServices
method to scan for implementations.
Manual Registration
You can also register individual options manually:
// Register DbUp options
services.RegisterDbUpOptions(configuration, options =>
{
options.UseDocker = true;
options.ScriptPath = "/app/scripts";
});
// Register database options
services.RegisterDbOptions(configuration, options =>
{
options.CommandTimeout = 5000;
options.GetPageQuery = CustomPaginationQuery;
});
Implementation Requirements
What You Must Implement
- Repository Classes: Implement
IRepository<T>
for your entities - Database Seeding: Implement
IDatabaseSeedService
if needed - Connection Factory: Ensure
IConnectionFactory
is properly implemented - Entity Models: Define your entity classes
Example Repository Registration
// Register your repository implementations
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IProductRepository, ProductRepository>();
// ... other repositories
Advanced Usage
Custom Pagination Query
services.RegisterDbOptions(configuration, options =>
{
options.GetPageQuery = (input, pageIndex, pageSize, totalCount, orderBy, pairs) =>
{
var offset = (pageIndex - 1) * pageSize;
var limit = pageSize;
// Custom pagination logic
if (pageSize > totalCount)
{
limit = totalCount;
}
return $"{input} {orderBy} LIMIT {limit} OFFSET {offset}";
};
});
Database Seeding
Note: You must implement IDatabaseSeedService
yourself:
public class DatabaseSeedService : IDatabaseSeedService
{
private readonly IDataAccess _dataAccess;
public DatabaseSeedService(IDataAccess dataAccess)
{
_dataAccess = dataAccess;
}
public async Task ApplySeeding()
{
// Check if seeding is needed
var userCount = await _dataAccess.LoadSingle<int, object>(
"SELECT COUNT(*) FROM Users", null, "DefaultConnection");
if (userCount == 0)
{
// Apply initial seed data
await _dataAccess.SaveData(
"INSERT INTO Users (Name, Email, IsActive) VALUES (@Name, @Email, @IsActive)",
new { Name = "Admin", Email = "admin@example.com", IsActive = true },
"DefaultConnection"
);
}
}
}
// Register the service
services.AddScoped<IDatabaseSeedService, DatabaseSeedService>();
Environment-Specific Configuration
// appsettings.Development.json
{
"DbUpOptions": {
"UseDocker": false,
"ScriptPath": "C:\\DevScripts\\Database"
}
}
// appsettings.Production.json
{
"DbUpOptions": {
"UseDocker": true,
"ScriptPath": "/app/scripts"
}
}
Dependencies
- CG.Infrastructure.Core: Provides the base service infrastructure and dependency injection support
- CG.Infrastructure.Configuration: Configuration management and connection options
- Dapper: High-performance micro ORM for data access
- dbup-core: Database migration framework
- dbup-sqlserver: SQL Server support for DbUp
- Microsoft.Data.SqlClient: SQL Server data provider
- Microsoft.Extensions.Configuration.Abstractions: Configuration system integration
- Microsoft.Extensions.DependencyInjection.Abstractions: Dependency injection support
- Microsoft.Extensions.Logging.Abstractions: Logging support
Integration with Infrastructure Suite
This library integrates with the broader infrastructure suite by:
- Implementing IService: Integrates with the automatic service registration system
- Configuration Integration: Uses the configuration library for connection management
- Service Extensions: Provides extension methods for easy service registration
- Dependency Injection: Seamlessly integrates with the DI container
- Logging Integration: Uses the logging infrastructure for migration tracking
Best Practices
- Script Organization: Organize scripts by version or feature in separate folders
- Transaction Management: Always use transactions for multi-step operations
- Connection Management: Use named connections for different database contexts
- Error Handling: Implement proper error handling and rollback mechanisms
- Performance: Use appropriate indexes and optimize SQL queries
- Security: Use parameterized queries to prevent SQL injection
- Testing: Test migrations in isolated environments before production
- Repository Implementation: Implement repositories for each entity type
- Service Registration: Manually register repository implementations or use assembly scanning
Important Notes
- This library provides interfaces and infrastructure, not complete implementations
- Repository classes must be implemented by consuming applications
- Database seeding service must be implemented by consuming applications
- Connection factory implementation must be provided
- Service registration for repositories may require manual configuration
Contributing
This library is part of the CG Infrastructure suite. For contributions, please follow the established patterns and ensure all tests pass.
License
This project is licensed under the terms specified in the LICENSE file.
Version History
- 3.10.8: Current stable release
- Supports .NET 9.0
- Includes comprehensive data access and migration capabilities
- Provides DbUp integration for database schema management
- Integrates with the infrastructure service registration system
- Note: Repository implementations must be provided by consumers
Support
For issues, questions, or contributions, please refer to the project repository or contact the maintainers.
Product | Versions 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. |
-
net9.0
- CG.Infrastructure.Configuration (>= 3.10.1)
- CG.Infrastructure.Core (>= 3.10.8)
- Dapper (>= 2.1.66)
- dbup-core (>= 6.0.4)
- dbup-sqlserver (>= 6.0.0)
- Microsoft.Data.SqlClient (>= 6.1.1)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.8)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.8)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on CG.Infrastructure.Data:
Package | Downloads |
---|---|
CG.Infrastructure.Mediator
Infra Mediator library with MediatR setup, extensions and database contexts |
|
CG.Infrastructure.Authentication
Infra Authentication library with AspNetCore.Identity setup, extensions and database contexts |
|
CG.Infrastructure.Authorization
Infra Authorization library with Duende setup, extensions and database contexts |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
3.10.9 | 148 | 8/20/2025 |
3.10.8 | 125 | 8/20/2025 |
3.10.7 | 112 | 8/15/2025 |
3.10.6 | 130 | 8/10/2025 |
3.10.5 | 150 | 6/18/2025 |
3.10.4 | 160 | 6/18/2025 |
3.10.3 | 265 | 6/9/2025 |
3.10.2 | 124 | 6/7/2025 |
3.10.1 | 85 | 6/7/2025 |
3.10.0 | 119 | 6/6/2025 |
3.9.7 | 175 | 3/3/2025 |
3.9.6 | 155 | 2/26/2025 |
3.9.5 | 162 | 2/11/2025 |
3.9.4 | 136 | 2/7/2025 |
3.9.3 | 138 | 2/3/2025 |
3.9.2 | 137 | 12/10/2024 |
3.9.1 | 124 | 12/10/2024 |
3.9.0 | 136 | 12/10/2024 |
3.0.13 | 195 | 8/13/2024 |
3.0.12 | 153 | 8/9/2024 |
3.0.11 | 166 | 8/9/2024 |
3.0.10 | 143 | 8/7/2024 |
3.0.9 | 84 | 7/31/2024 |
3.0.8 | 101 | 7/16/2024 |
3.0.7 | 149 | 3/25/2024 |
3.0.6 | 113 | 3/25/2024 |
3.0.5 | 113 | 3/25/2024 |
3.0.4 | 112 | 3/25/2024 |
3.0.3 | 116 | 3/25/2024 |
3.0.2 | 117 | 2/26/2024 |
3.0.1 | 140 | 2/26/2024 |
3.0.0 | 167 | 2/19/2024 |
2.0.0 | 321 | 5/16/2023 |
1.0.1 | 499 | 6/17/2022 |
1.0.0 | 484 | 5/26/2022 |