using Microsoft.EntityFrameworkCore.Design;
namespace FileShare_EFCore.Database
{
///
/// 设计时 DbContext 工厂,用于 EF Core 迁移工具生成迁移代码。
///
public class AppDataContextFactory : IDesignTimeDbContextFactory
{
///
/// 创建用于设计时的 AppDataContext 实例,默认使用 SQLite 提供程序。
///
/// 命令行参数。
/// 配置好的数据上下文实例。
public AppDataContext CreateDbContext(string[] args)
{
return new AppDataContext(DesignTimeDatabaseConfiguration.Create(args));
}
}
///
/// SQLite 迁移设计时工厂。
///
public sealed class SqliteAppDataContextFactory : IDesignTimeDbContextFactory
{
///
public SqliteAppDataContext CreateDbContext(string[] args)
=> new(DesignTimeDatabaseConfiguration.Create(args, DatabaseProvider.SQLite));
}
///
/// SQL Server 迁移设计时工厂。
///
public sealed class SqlServerAppDataContextFactory : IDesignTimeDbContextFactory
{
///
public SqlServerAppDataContext CreateDbContext(string[] args)
=> new(DesignTimeDatabaseConfiguration.Create(args, DatabaseProvider.SqlServer));
}
///
/// PostgreSQL 迁移设计时工厂。
///
public sealed class PostgreSqlAppDataContextFactory : IDesignTimeDbContextFactory
{
///
public PostgreSqlAppDataContext CreateDbContext(string[] args)
=> new(DesignTimeDatabaseConfiguration.Create(args, DatabaseProvider.PostgreSQL));
}
///
/// MySQL 迁移设计时工厂。
///
public sealed class MySqlAppDataContextFactory : IDesignTimeDbContextFactory
{
///
public MySqlAppDataContext CreateDbContext(string[] args)
=> new(DesignTimeDatabaseConfiguration.Create(args, DatabaseProvider.MySQL));
}
///
/// 为设计时工具(dotnet ef migrations)提供数据库连接配置。
///
internal static class DesignTimeDatabaseConfiguration
{
///
/// 解析命令行参数中的 --provider 选项,创建对应的 。
/// 未指定提供程序时默认使用 SQLite。
///
/// 命令行参数。
/// 未指定时的默认数据库提供程序。
/// 对应数据库提供程序的配置。
public static DatabaseConfiguration Create(string[] args, DatabaseProvider defaultProvider = DatabaseProvider.SQLite)
{
DatabaseProviderRegistry.RegisterDefaults();
var provider = GetProvider(args) ?? defaultProvider;
return provider switch
{
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"),
};
}
///
/// 从命令行参数中解析 --provider 选项的值。
/// 支持 --provider sqlite 和 --provider=sqlite 两种格式。
///
/// 命令行参数。
/// 解析到的数据库提供程序,未指定或无法识别时返回 null。
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(value, ignoreCase: true, out var provider))
{
return provider;
}
}
return null;
}
}
}