EntityFrameworkInstaller.cs 2.61 KB
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Rcs.Domain.Settings;
using Rcs.Infrastructure.DB.MsSql;

namespace Rcs.Infrastructure.Installs
{
    public static class EntityFrameworkInstaller
    {
        public static void InstallEntityFramework(this WebApplicationBuilder builder)
        {
            var appSettings = builder.Configuration.GetSection(nameof(AppSettings)).Get<AppSettings>();
            if (appSettings != null)
            {
                var msSqlSettings = appSettings.ConnSql;
                builder.Services.AddDbContext<AppDbContext>(options => options.UseNpgsql(msSqlSettings.ConnectionString));
                builder.Services.AddScoped<IAppDbContext>(provider => provider.GetService<AppDbContext>());
            }
        }

        public static void SeedDatabase(AppDbContext appDbContext)
        {
            try
            {
                // 检查是否有待应用的迁移
                var pendingMigrations = appDbContext.Database.GetPendingMigrations();
                
                if (pendingMigrations.Any())
                {
                    // 如果有迁移文件,则应用迁移
                    appDbContext.Database.Migrate();
                }
                else if (!appDbContext.Database.CanConnect())
                {
                    // 数据库不存在,直接创建
                    appDbContext.Database.EnsureCreated();
                }
                else
                {
                    var appliedMigrations = appDbContext.Database.GetAppliedMigrations();
                    if (appliedMigrations.Count() == 0)
                    {
                        // 数据库存在但没有应用过迁移,直接创建表结构
                        appDbContext.Database.EnsureCreated();
                    }
                }
            }
            catch (Exception ex)
            {
                // 如果检查迁移失败(可能是数据库结构问题),尝试删除并重新创建
                // 注意:这在生产环境中应该谨慎使用
                if (ex.Message.Contains("timestamp") || ex.Message.Contains("relation") || ex.Message.Contains("does not exist"))
                {
                    // 删除数据库并重新创建
                    appDbContext.Database.EnsureDeleted();
                    appDbContext.Database.EnsureCreated();
                }
                else
                {
                    throw;
                }
            }
        }
    }
}