Siemens.AspNet.DbProvider
0.1.0-alpha.303
Prefix Reserved
See the version list below for details.
dotnet add package Siemens.AspNet.DbProvider --version 0.1.0-alpha.303
NuGet\Install-Package Siemens.AspNet.DbProvider -Version 0.1.0-alpha.303
<PackageReference Include="Siemens.AspNet.DbProvider" Version="0.1.0-alpha.303" />
<PackageVersion Include="Siemens.AspNet.DbProvider" Version="0.1.0-alpha.303" />
<PackageReference Include="Siemens.AspNet.DbProvider" />
paket add Siemens.AspNet.DbProvider --version 0.1.0-alpha.303
#r "nuget: Siemens.AspNet.DbProvider, 0.1.0-alpha.303"
#:package Siemens.AspNet.DbProvider@0.1.0-alpha.303
#addin nuget:?package=Siemens.AspNet.DbProvider&version=0.1.0-alpha.303&prerelease
#tool nuget:?package=Siemens.AspNet.DbProvider&version=0.1.0-alpha.303&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.11)
- MySql.Data (>= 9.4.0)
- Siemens.AspNet.DbProvider.Contracts (>= 0.1.0-alpha.303)
- Siemens.AspNet.ErrorHandling.Contracts (>= 5.2.3)
- Siemens.AspNet.MinimalApi.Sdk (>= 0.1.0-alpha.303)
- Snowflake.Data (>= 4.8.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.