using Microsoft.EntityFrameworkCore; using Microsoft.Data.Sqlite; using MiGu.Server.Wms; namespace MiGu.Server.Persistence; public static class PlatformPersistence { public static IServiceCollection AddPlatformPersistence(this IServiceCollection services, IConfiguration configuration) { services.AddDbContext((sp, options) => { var env = sp.GetRequiredService(); var provider = configuration["Database:Provider"] ?? "sqlite"; var connection = ResolveConnectionString(configuration, env, provider); switch (provider.Trim().ToLowerInvariant()) { case "sqlite": options.UseSqlite(connection); break; case "mysql": options.UseMySql(connection, ServerVersion.AutoDetect(connection)); break; case "postgres": case "postgresql": case "npgsql": options.UseNpgsql(connection); break; case "sqlserver": case "mssql": options.UseSqlServer(connection); break; default: throw new InvalidOperationException($"未知数据库 Provider: {provider}"); } }); services.AddScoped(); services.AddScoped(); return services; } public static async Task EnsurePlatformDatabaseAsync(this IServiceProvider services) { using var scope = services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); await db.Database.EnsureCreatedAsync(); } private static string ResolveConnectionString(IConfiguration configuration, IWebHostEnvironment env, string provider) { var key = provider.Trim().ToLowerInvariant() switch { "postgres" or "postgresql" or "npgsql" => "PostgreSQL", "mssql" => "SqlServer", _ => provider }; var configured = configuration.GetConnectionString(key) ?? configuration.GetConnectionString("Platform"); if (!string.IsNullOrWhiteSpace(configured)) { return IsSqlite(provider) ? NormalizeSqliteConnection(configured, env) : configured; } var dataDir = Path.Combine(env.ContentRootPath, "data"); Directory.CreateDirectory(dataDir); return $"Data Source={Path.Combine(dataDir, "platform.db")}"; } private static bool IsSqlite(string provider) => string.Equals(provider.Trim(), "sqlite", StringComparison.OrdinalIgnoreCase); private static string NormalizeSqliteConnection(string connection, IWebHostEnvironment env) { var builder = new SqliteConnectionStringBuilder(connection); if (string.IsNullOrWhiteSpace(builder.DataSource)) return connection; if (builder.DataSource is ":memory:") return connection; if (!Path.IsPathRooted(builder.DataSource)) { builder.DataSource = Path.Combine(env.ContentRootPath, builder.DataSource); } var dir = Path.GetDirectoryName(builder.DataSource); if (!string.IsNullOrWhiteSpace(dir)) Directory.CreateDirectory(dir); return builder.ToString(); } }