122 lines
3.1 KiB
Markdown
122 lines
3.1 KiB
Markdown
|
|
# DbContext 工厂
|
|||
|
|
|
|||
|
|
> 所属模块:[数据库切换支持](./概览.md)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 接口定义
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// Data/IDbContextFactory.cs
|
|||
|
|
using WCTDataMiner.Data;
|
|||
|
|
|
|||
|
|
namespace WCTDataMiner.Data;
|
|||
|
|
|
|||
|
|
public interface IDbContextFactory
|
|||
|
|
{
|
|||
|
|
WctMinerDbContext CreateDbContext();
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 工厂实现
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// Data/DbContextFactory.cs
|
|||
|
|
using Microsoft.EntityFrameworkCore;
|
|||
|
|
using Microsoft.Extensions.Configuration;
|
|||
|
|
|
|||
|
|
namespace WCTDataMiner.Data;
|
|||
|
|
|
|||
|
|
public class DbContextFactory : IDbContextFactory
|
|||
|
|
{
|
|||
|
|
private readonly IConfiguration _configuration;
|
|||
|
|
|
|||
|
|
public DbContextFactory(IConfiguration configuration)
|
|||
|
|
{
|
|||
|
|
_configuration = configuration;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public WctMinerDbContext CreateDbContext()
|
|||
|
|
{
|
|||
|
|
var dbType = _configuration["Database:Type"]?.ToLower() ?? "sqlite";
|
|||
|
|
var optionsBuilder = new DbContextOptionsBuilder<WctMinerDbContext>();
|
|||
|
|
|
|||
|
|
switch (dbType)
|
|||
|
|
{
|
|||
|
|
case "postgresql":
|
|||
|
|
case "postgres":
|
|||
|
|
var pgConnStr = BuildPostgreSqlConnectionString();
|
|||
|
|
optionsBuilder.UseNpgsql(pgConnStr);
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case "sqlite":
|
|||
|
|
default:
|
|||
|
|
var dbPath = _configuration["Database:Path"] ?? "./data/database/wctminer.db";
|
|||
|
|
EnsureDirectoryExists(dbPath);
|
|||
|
|
optionsBuilder.UseSqlite($"Data Source={dbPath}");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#if DEBUG
|
|||
|
|
optionsBuilder.EnableSensitiveDataLogging();
|
|||
|
|
optionsBuilder.EnableDetailedErrors();
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
return new WctMinerDbContext(optionsBuilder.Options);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private string BuildPostgreSqlConnectionString()
|
|||
|
|
{
|
|||
|
|
var host = _configuration["Database:Host"] ?? "localhost";
|
|||
|
|
var port = _configuration["Database:Port"] ?? "5432";
|
|||
|
|
var name = _configuration["Database:Name"] ?? "wctminer";
|
|||
|
|
var user = _configuration["Database:User"] ?? "postgres";
|
|||
|
|
var password = _configuration["Database:Password"] ?? "";
|
|||
|
|
|
|||
|
|
return $"Host={host};Port={port};Database={name};Username={user};Password={password}";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static void EnsureDirectoryExists(string dbPath)
|
|||
|
|
{
|
|||
|
|
var directory = Path.GetDirectoryName(dbPath);
|
|||
|
|
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
|||
|
|
{
|
|||
|
|
Directory.CreateDirectory(directory);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 依赖注入扩展
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// Extensions/ServiceCollectionExtensions.cs
|
|||
|
|
using Microsoft.Extensions.DependencyInjection;
|
|||
|
|
using WCTDataMiner.Data;
|
|||
|
|
|
|||
|
|
namespace WCTDataMiner.Extensions;
|
|||
|
|
|
|||
|
|
public static class ServiceCollectionExtensions
|
|||
|
|
{
|
|||
|
|
public static IServiceCollection AddDatabaseServices(
|
|||
|
|
this IServiceCollection services,
|
|||
|
|
IConfiguration configuration)
|
|||
|
|
{
|
|||
|
|
// 注册 DbContext 工厂
|
|||
|
|
services.AddScoped<IDbContextFactory, DbContextFactory>();
|
|||
|
|
|
|||
|
|
// 注册 DbContext(通过工厂创建)
|
|||
|
|
services.AddScoped<WctMinerDbContext>(sp =>
|
|||
|
|
{
|
|||
|
|
var factory = sp.GetRequiredService<IDbContextFactory>();
|
|||
|
|
return factory.CreateDbContext();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return services;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|