Siemens.AspNet.DbProvider
0.1.0-alpha.165
Prefix Reserved
See the version list below for details.
dotnet add package Siemens.AspNet.DbProvider --version 0.1.0-alpha.165
NuGet\Install-Package Siemens.AspNet.DbProvider -Version 0.1.0-alpha.165
<PackageReference Include="Siemens.AspNet.DbProvider" Version="0.1.0-alpha.165" />
<PackageVersion Include="Siemens.AspNet.DbProvider" Version="0.1.0-alpha.165" />
<PackageReference Include="Siemens.AspNet.DbProvider" />
paket add Siemens.AspNet.DbProvider --version 0.1.0-alpha.165
#r "nuget: Siemens.AspNet.DbProvider, 0.1.0-alpha.165"
#:package Siemens.AspNet.DbProvider@0.1.0-alpha.165
#addin nuget:?package=Siemens.AspNet.DbProvider&version=0.1.0-alpha.165&prerelease
#tool nuget:?package=Siemens.AspNet.DbProvider&version=0.1.0-alpha.165&prerelease
Siemens.AspNet.DbProvider
A powerful, flexible database provider for .NET applications that simplifies database interactions with multiple database systems.
Features
Multi-Database Support: Works with multiple database providers including:
- MySQL/MariaDB
- Snowflake
- SingleStore (limited support)
Type-Safe Queries: Strongly-typed query results with automatic mapping between database and .NET types
Dynamic Data Operations:
- Create, read, update, and delete table data
- Dynamic table schema management
- Copy tables and data between tables
Transaction Support: Full transaction support across all database providers
Parameterized Queries: Protection against SQL injection through parameterized queries
SQL Analytics: Built-in query analytics and performance monitoring
File Import: Read data from CSV and Excel files with built-in form file readers
Data Export: Export data and schema definitions to CSV and Excel formats
Migration Support: Database migration utilities for schema evolution
Error Handling: Comprehensive error handling with detailed exception information
Installation
Prerequisites
- .NET 9.0 or higher
- Required database client libraries:
- MySQL: MySql.Data package (included as dependency)
- Snowflake: Snowflake.Data package (included as dependency)
NuGet Package
dotnet add package Siemens.AspNet.DbProvider
Getting Started
Basic Setup
Register the database provider in your Program.cs
or startup class:
// Add base services
builder.Services.AddDbProvider(builder.Configuration);
// Add specific provider(s) you need
builder.Services.AddMySqlProvider(builder.Configuration);
// and/or
builder.Services.AddSnowflakeProvider(builder.Configuration);
// If using MySQL, add connection factory
builder.Services.AddMySqlConnectionFactory();
// If using dynamic data features
builder.Services.AddDatabaseService(builder.Configuration);
// If using form file readers (CSV, Excel)
builder.Services.AddFormFileReaderProvider();
// If using data export features
builder.Services.AddDataExporter();
builder.Services.AddSchemaExporter();
Connection String Configuration
In your appsettings.json
file:
{
"ConnectionStrings": {
"MySqlConnection": "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;",
"SnowflakeConnection": "account=myAccount;user=myUser;password=myPassword;DB=myDatabase;SCHEMA=mySchema;"
}
}
Basic Usage
Executing Queries
public class UserRepository
{
private readonly IDbQueryProvider _dbQueryProvider;
public UserRepository(IDbQueryProvider dbQueryProvider)
{
_dbQueryProvider = dbQueryProvider;
}
public async Task<User> GetUserByIdAsync(int userId)
{
const string sql = "SELECT * FROM Users WHERE Id = @UserId";
var parameters = new { UserId = userId };
return await _dbQueryProvider.QueryFirstOrDefaultAsync<User>(sql, parameters);
}
public async Task<IEnumerable<User>> GetAllUsersAsync()
{
const string sql = "SELECT * FROM Users";
return await _dbQueryProvider.QueryAsync<User>(sql);
}
public async Task<int> CreateUserAsync(User user)
{
const string sql = "INSERT INTO Users (Name, Email) VALUES (@Name, @Email); SELECT LAST_INSERT_ID();";
var parameters = new { user.Name, user.Email };
return await _dbQueryProvider.ExecuteScalarAsync<int>(sql, parameters);
}
}
Using Transactions
public async Task TransferFundsAsync(int fromAccountId, int toAccountId, decimal amount)
{
using var transaction = await _dbQueryProvider.BeginTransactionAsync();
try
{
await _dbQueryProvider.ExecuteAsync(
"UPDATE Accounts SET Balance = Balance - @Amount WHERE Id = @FromId",
new { Amount = amount, FromId = fromAccountId },
transaction);
await _dbQueryProvider.ExecuteAsync(
"UPDATE Accounts SET Balance = Balance + @Amount WHERE Id = @ToId",
new { Amount = amount, ToId = toAccountId },
transaction);
await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
Dynamic Data Features
The Dynamic Data module provides powerful schema-agnostic database operations without writing SQL:
Service Registration
// Register the DatabaseService
builder.Services.AddDatabaseService(builder.Configuration);
Table Schema Management
public class SchemaService
{
private readonly IDatabaseService _databaseService;
private readonly DbConnectionInfo _dbConnectionInfo;
public SchemaService(IDatabaseService databaseService, IDbTypeProvider dbTypeProvider, IConfiguration configuration)
{
_databaseService = databaseService;
// Create connection info
var dbProvider = dbTypeProvider.GetFor(DatabaseProvider.MySql);
_dbConnectionInfo = dbProvider.ParseConnectionString(
configuration.GetConnectionString("MySqlConnection"));
}
// Create a new table with specified columns
public async Task<SimplifiedTableSchema> CreateProductTableAsync()
{
// Define columns for the table
var columns = new List<SimpleColumn>
{
new("Id", SimplifiedDbType.Integer) { IsPrimaryKey = true, IsAutoIncrement = true },
new("ProductName", SimplifiedDbType.String) { MaxLength = 100, IsNullable = false },
new("Description", SimplifiedDbType.String) { MaxLength = 500 },
new("Price", SimplifiedDbType.Decimal) { IsNullable = false },
new("CreatedAt", SimplifiedDbType.DateTime) { IsNullable = false },
new("IsActive", SimplifiedDbType.Bool) { IsNullable = false, DefaultValue = "1" }
};
// Create the table
return await _databaseService.AddTableAsync(
"Products",
columns.ToImmutableList(),
_dbConnectionInfo);
}
// Add a column to existing table
public async Task<int> AddCategoryColumnAsync()
{
// Get table schema
var tableSchema = await _databaseService.GetTableSchemaAsync(
"Products",
_dbConnectionInfo);
// Add column
return await _databaseService.AddColumnToAsync(
tableSchema,
new SimpleColumn("Category", SimplifiedDbType.String) { MaxLength = 50 });
}
// Copy table structure (with or without data)
public async Task<SimplifiedTableSchema> CreateProductsBackupTableAsync()
{
// Get existing table schema
var existingTable = await _databaseService.GetTableSchemaAsync(
"Products",
_dbConnectionInfo);
// Create copy with data
return await _databaseService.CopyTableAsync(
"Products_Backup",
existingTable,
copyData: true);
}
}
Dynamic CRUD Operations
public class ProductRepository
{
private readonly IDatabaseService _databaseService;
private readonly SimplifiedTableSchema _tableSchema;
public ProductRepository(IDatabaseService databaseService)
{
_databaseService = databaseService;
// This would be retrieved once and cached/injected in a real app
_tableSchema = databaseService.GetTableSchemaAsync("Products", connectionInfo).Result;
}
// Insert data
public async Task<InsertDataResult> AddProductsAsync(IEnumerable<Dictionary<string, object>> products)
{
// Convert to dynamic data objects
var dynamicData = new DynamicDataObjectsWithLocation(products);
// Add audit values
var auditValues = new Dictionary<string, string>
{
{ "CreatedAt", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") },
{ "IsActive", "1" }
}.ToImmutableDictionary();
// Insert data
return await _databaseService.InsertDataAsync(_tableSchema, dynamicData, auditValues);
}
// Query data with filtering
public async Task<IEnumerable<ProductDto>> GetActiveProductsAsync()
{
// Create where condition
var wherePart = new WherePart();
wherePart.AddEqualCondition("IsActive", "1");
// Define sort order
var sortOrder = new SortOrder("ProductName", ColumnSortOrder.Asc);
// Get data with specific columns
return await _databaseService.GetDataAsync<ProductDto>(
_tableSchema,
wherePart,
sortOrder,
"Id", "ProductName", "Price", "Category");
}
// Query with pagination
public async Task<PageInfo<ProductDto>> GetProductsPagedAsync(int pageNumber, int pageSize)
{
// Create pagination
var pagination = new Pagination(pageNumber, pageSize);
// Create sort order
var sortOrder = new SortOrder("ProductName", ColumnSortOrder.Asc);
// Get paginated data
return await _databaseService.GetDataPageWiseAsync<ProductDto>(
_tableSchema,
pagination,
new WherePart(),
sortOrder);
}
// Update data
public async Task<UpdateDataResult> UpdateProductPricesAsync(
IEnumerable<Dictionary<string, object>> productsWithNewPrices)
{
// Convert to dynamic data objects
var dynamicData = new DynamicDataObjectsWithLocation(productsWithNewPrices);
// Add audit values
var auditValues = new Dictionary<string, string>
{
{ "ModifiedAt", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") }
}.ToImmutableDictionary();
// Update data
return await _databaseService.UpdateDataAsync(_tableSchema, dynamicData, auditValues);
}
// Delete data by condition
public async Task<int> DeleteDiscontinuedProductsAsync(string category)
{
var wherePart = new WherePart();
wherePart.AddEqualCondition("Category", category);
wherePart.AddEqualCondition("IsActive", "0");
return await _databaseService.DeleteDataAsync(_tableSchema, wherePart);
}
}
Powerful Data Import and Export
public class DataImportExportService
{
private readonly IFormFileReaderProvider _fileReaderProvider;
private readonly IDatabaseService _databaseService;
private readonly IDbDataExporter _dataExporter;
private readonly IDbSchemaExporter _schemaExporter;
private readonly SimplifiedTableSchema _tableSchema;
public DataImportExportService(
IFormFileReaderProvider fileReaderProvider,
IDatabaseService databaseService,
IDbDataExporter dataExporter,
IDbSchemaExporter schemaExporter)
{
_fileReaderProvider = fileReaderProvider;
_databaseService = databaseService;
_dataExporter = dataExporter;
_schemaExporter = schemaExporter;
// This would be retrieved once and cached/injected in a real app
_tableSchema = databaseService.GetTableSchemaAsync("Products", connectionInfo).Result;
}
// Import products from CSV file
public async Task<InsertDataResult> ImportProductsFromCsvAsync(IFormFile csvFile)
{
// Get CSV reader
var reader = _fileReaderProvider.GetReader(FormFileReaderInfo.CsvReader);
// Read data as dynamic objects
var products = await reader.ReadAsDynamicObjectsAsync(csvFile);
// Insert into database
return await _databaseService.InsertDataAsync(_tableSchema, products);
}
// Export data to CSV file
public async Task ExportProductsToCsvAsync(string filePath)
{
// Get product data
var data = await _databaseService.GetDataAsync<Dictionary<string, object>>(
_tableSchema,
"*");
// Export to CSV
await _dataExporter.ExportAsync(
_tableSchema.TableName,
data,
filePath,
DbDataExporterInfo.CsvExporter);
}
// Export schema to Excel
public async Task ExportSchemaToExcelAsync(string filePath)
{
await _schemaExporter.ExportAsync(
_tableSchema,
filePath,
DbSchemaExporterInfo.ExcelExporter);
}
}
Advanced Features
SQL Analytics
The provider includes SQL analytics that can help you monitor and optimize your queries:
// Enable SQL analytics in your configuration
public void ConfigureServices(IServiceCollection services)
{
services.AddMySqlAnalyticsHandler(Configuration);
// ... other services
}
// Use analytics-enabled methods
public class PerformanceMonitoringService
{
private readonly IDbQueryProvider _dbQueryProvider;
public PerformanceMonitoringService(IDbQueryProvider dbQueryProvider)
{
_dbQueryProvider = dbQueryProvider;
}
public async Task<QueryPerformanceInfo> GetUserDataWithPerformanceMetrics(int userId)
{
var sql = @"
SELECT u.*, p.*
FROM Users u
JOIN UserProfiles p ON u.Id = p.UserId
WHERE u.Id = @UserId";
var (users, metrics) = await _dbQueryProvider.QueryWithAnalyticsAsync<UserWithProfile>(
sql,
new { UserId = userId });
// Return both query results and performance metrics
return new QueryPerformanceInfo
{
Data = users,
ExecutionTimeMs = metrics.ExecutionTime.TotalMilliseconds,
RowsAffected = metrics.RowCount,
SqlExecuted = metrics.FormatedSql
};
}
}
Logging and Error Handling
The provider offers comprehensive logging and error handling:
public class DataAccessService
{
private readonly IDbQueryProvider _dbQueryProvider;
private readonly ILogger<DataAccessService> _logger;
public DataAccessService(IDbQueryProvider dbQueryProvider, ILogger<DataAccessService> logger)
{
_dbQueryProvider = dbQueryProvider;
_logger = logger;
}
public async Task<IEnumerable<User>> GetUsersWithLoggingAsync()
{
const string sql = "SELECT * FROM Users";
try
{
// Execute query with logging
var (users, logs) = await _dbQueryProvider.QueryWithLogAsync<User>(sql);
// Log query information
_logger.LogInformation(
"Query executed successfully: {SqlQuery}, Rows: {RowCount}, Time: {ExecutionTimeMs}ms",
logs.FormatedSql,
logs.RowCount,
logs.ExecutionTime.TotalMilliseconds);
return users;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error executing query");
throw;
}
}
}
Database Types Support
The provider supports various database types:
MySQL Types
- String types: varchar, tinytext, text, mediumtext, longtext, etc.
- Numeric types: int, tinyint, smallint, bigint, decimal, float, double
- Date/time types: datetime, date, timestamp, time, year
- Boolean type
- JSON type
Snowflake Types
- String types: varchar, string, text
- Numeric types: integer, smallint, bigint, decimal, float, double
- Date/time types: datetime, date, time, timestamp
- Boolean type
- JSON type
Simplified Database Types
For cross-database compatibility, the library provides simplified types:
// Simplified types abstract the actual database type
public enum SimplifiedDbType
{
String,
Integer,
Decimal,
Bool,
DateTime,
Date,
Json
}
// Example using simplified types to create a table
var columns = new List<SimpleColumn>
{
new("Id", SimplifiedDbType.Integer) { IsPrimaryKey = true, IsAutoIncrement = true },
new("Name", SimplifiedDbType.String) { MaxLength = 100 },
new("IsActive", SimplifiedDbType.Bool),
new("CreatedAt", SimplifiedDbType.DateTime),
new("Config", SimplifiedDbType.Json)
};
Contributing
Contributions to the Siemens.AspNet.DbProvider are welcome. Please ensure that your code adheres to the existing style and includes appropriate tests.
License
Copyright 2025 (c) Siemens AG. All rights reserved.
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
- EPPlus (>= 4.5.3.3)
- Extensions.Pack (>= 6.0.6)
- MySql.Data (>= 9.3.0)
- Siemens.AspNet.DbProvider.Contracts (>= 0.1.0-alpha.165)
- Siemens.AspNet.ErrorHandling.Contracts (>= 5.1.2)
- Siemens.AspNet.MinimalApi.Sdk (>= 0.1.0-alpha.165)
- Snowflake.Data (>= 4.5.0)
- System.Drawing.Common (>= 9.0.6)
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 |
---|---|---|
0.1.0-alpha.224 | 0 | 7/30/2025 |
0.1.0-alpha.222 | 171 | 7/16/2025 |
0.1.0-alpha.219 | 153 | 7/14/2025 |
0.1.0-alpha.217 | 70 | 7/11/2025 |
0.1.0-alpha.212 | 153 | 7/8/2025 |
0.1.0-alpha.211 | 129 | 7/3/2025 |
0.1.0-alpha.207 | 103 | 7/3/2025 |
0.1.0-alpha.206 | 283 | 6/30/2025 |
0.1.0-alpha.205 | 83 | 6/27/2025 |
0.1.0-alpha.202 | 83 | 6/27/2025 |
0.1.0-alpha.200 | 87 | 6/27/2025 |
0.1.0-alpha.198 | 86 | 6/27/2025 |
0.1.0-alpha.196 | 92 | 6/27/2025 |
0.1.0-alpha.195 | 85 | 6/27/2025 |
0.1.0-alpha.194 | 84 | 6/27/2025 |
0.1.0-alpha.193 | 86 | 6/27/2025 |
0.1.0-alpha.192 | 89 | 6/27/2025 |
0.1.0-alpha.191 | 86 | 6/27/2025 |
0.1.0-alpha.189 | 109 | 6/26/2025 |
0.1.0-alpha.188 | 160 | 6/26/2025 |
0.1.0-alpha.187 | 101 | 6/26/2025 |
0.1.0-alpha.186 | 121 | 6/26/2025 |
0.1.0-alpha.185 | 105 | 6/26/2025 |
0.1.0-alpha.184 | 109 | 6/26/2025 |
0.1.0-alpha.183 | 109 | 6/26/2025 |
0.1.0-alpha.182 | 104 | 6/26/2025 |
0.1.0-alpha.181 | 119 | 6/25/2025 |
0.1.0-alpha.180 | 118 | 6/24/2025 |
0.1.0-alpha.179 | 109 | 6/23/2025 |
0.1.0-alpha.178 | 189 | 6/23/2025 |
0.1.0-alpha.176 | 111 | 6/23/2025 |
0.1.0-alpha.174 | 116 | 6/19/2025 |
0.1.0-alpha.173 | 152 | 6/19/2025 |
0.1.0-alpha.172 | 114 | 6/17/2025 |
0.1.0-alpha.171 | 160 | 6/16/2025 |
0.1.0-alpha.169 | 110 | 6/16/2025 |
0.1.0-alpha.165 | 244 | 6/13/2025 |
0.1.0-alpha.164 | 219 | 6/13/2025 |
0.1.0-alpha.163 | 224 | 6/13/2025 |
0.1.0-alpha.160 | 255 | 6/12/2025 |
0.1.0-alpha.159 | 343 | 6/11/2025 |
0.1.0-alpha.158 | 262 | 6/11/2025 |
0.1.0-alpha.143 | 257 | 6/11/2025 |
0.1.0-alpha.142 | 256 | 6/11/2025 |
0.1.0-alpha.140 | 265 | 6/11/2025 |
0.1.0-alpha.139 | 262 | 6/10/2025 |
0.1.0-alpha.138 | 238 | 6/9/2025 |
0.1.0-alpha.137 | 43 | 6/7/2025 |
0.1.0-alpha.136 | 43 | 6/7/2025 |
0.1.0-alpha.135 | 79 | 6/6/2025 |
0.1.0-alpha.134 | 77 | 6/6/2025 |
0.1.0-alpha.130 | 119 | 6/5/2025 |
0.1.0-alpha.129 | 118 | 6/4/2025 |
0.1.0-alpha.128 | 112 | 6/4/2025 |