FileShare/FileShare-EFCore/Database/AppDataContextFactory.cs

121 lines
4.9 KiB
C#
Raw Normal View History

2026-05-21 15:52:36 +08:00
using Microsoft.EntityFrameworkCore.Design;
2026-05-22 14:29:22 +08:00
namespace FileShare_EFCore.Database
2026-05-21 15:52:36 +08:00
{
/// <summary>
/// 设计时 DbContext 工厂,用于 EF Core 迁移工具生成迁移代码。
/// </summary>
public class AppDataContextFactory : IDesignTimeDbContextFactory<AppDataContext>
{
/// <summary>
/// 创建用于设计时的 AppDataContext 实例,默认使用 SQLite 提供程序。
/// </summary>
/// <param name="args">命令行参数。</param>
/// <returns>配置好的数据上下文实例。</returns>
public AppDataContext CreateDbContext(string[] args)
{
return new AppDataContext(DesignTimeDatabaseConfiguration.Create(args));
}
}
/// <summary>
/// SQLite 迁移设计时工厂。
/// </summary>
public sealed class SqliteAppDataContextFactory : IDesignTimeDbContextFactory<SqliteAppDataContext>
{
/// <inheritdoc />
public SqliteAppDataContext CreateDbContext(string[] args)
=> new(DesignTimeDatabaseConfiguration.Create(args, DatabaseProvider.SQLite));
}
/// <summary>
/// SQL Server 迁移设计时工厂。
/// </summary>
public sealed class SqlServerAppDataContextFactory : IDesignTimeDbContextFactory<SqlServerAppDataContext>
{
/// <inheritdoc />
public SqlServerAppDataContext CreateDbContext(string[] args)
=> new(DesignTimeDatabaseConfiguration.Create(args, DatabaseProvider.SqlServer));
}
/// <summary>
/// PostgreSQL 迁移设计时工厂。
/// </summary>
public sealed class PostgreSqlAppDataContextFactory : IDesignTimeDbContextFactory<PostgreSqlAppDataContext>
{
/// <inheritdoc />
public PostgreSqlAppDataContext CreateDbContext(string[] args)
=> new(DesignTimeDatabaseConfiguration.Create(args, DatabaseProvider.PostgreSQL));
}
/// <summary>
/// MySQL 迁移设计时工厂。
/// </summary>
public sealed class MySqlAppDataContextFactory : IDesignTimeDbContextFactory<MySqlAppDataContext>
{
/// <inheritdoc />
public MySqlAppDataContext CreateDbContext(string[] args)
=> new(DesignTimeDatabaseConfiguration.Create(args, DatabaseProvider.MySQL));
}
/// <summary>
/// 为设计时工具dotnet ef migrations提供数据库连接配置。
/// </summary>
2026-05-21 15:52:36 +08:00
internal static class DesignTimeDatabaseConfiguration
{
/// <summary>
/// 解析命令行参数中的 --provider 选项,创建对应的 <see cref="DatabaseConfiguration"/>。
/// 未指定提供程序时默认使用 SQLite。
/// </summary>
/// <param name="args">命令行参数。</param>
/// <param name="defaultProvider">未指定时的默认数据库提供程序。</param>
/// <returns>对应数据库提供程序的配置。</returns>
2026-05-21 15:52:36 +08:00
public static DatabaseConfiguration Create(string[] args, DatabaseProvider defaultProvider = DatabaseProvider.SQLite)
{
DatabaseProviderRegistry.RegisterDefaults();
var provider = GetProvider(args) ?? defaultProvider;
return provider switch
{
2026-05-22 14:29:22 +08:00
DatabaseProvider.SQLite => DatabaseConfiguration.ForSQLite("fileshare-api.db"),
DatabaseProvider.SqlServer => DatabaseConfiguration.ForSqlServer("(localdb)\\MSSQLLocalDB", "FileShareApi"),
DatabaseProvider.PostgreSQL => DatabaseConfiguration.ForPostgreSQL("localhost", "fileshare_api", "postgres", "postgres"),
DatabaseProvider.MySQL => DatabaseConfiguration.ForMySQL("localhost", "fileshare_api", "root", "root"),
_ => DatabaseConfiguration.ForSQLite("fileshare-api.db"),
2026-05-21 15:52:36 +08:00
};
}
/// <summary>
/// 从命令行参数中解析 --provider 选项的值。
/// 支持 <c>--provider sqlite</c> 和 <c>--provider=sqlite</c> 两种格式。
/// </summary>
/// <param name="args">命令行参数。</param>
/// <returns>解析到的数据库提供程序,未指定或无法识别时返回 null。</returns>
2026-05-21 15:52:36 +08:00
private static DatabaseProvider? GetProvider(string[] args)
{
for (var i = 0; i < args.Length; i++)
{
var arg = args[i];
string? value = null;
if (arg.Equals("--provider", StringComparison.OrdinalIgnoreCase) && i + 1 < args.Length)
{
value = args[i + 1];
}
else if (arg.StartsWith("--provider=", StringComparison.OrdinalIgnoreCase))
{
value = arg["--provider=".Length..];
}
if (!string.IsNullOrWhiteSpace(value)
&& Enum.TryParse<DatabaseProvider>(value, ignoreCase: true, out var provider))
{
return provider;
}
}
return null;
}
}
}