C# 为实体框架核心中的所有数据库创建和应用迁移
我有C# 为实体框架核心中的所有数据库创建和应用迁移,c#,entity-framework,migration,entity-framework-core,entity-framework-migrations,C#,Entity Framework,Migration,Entity Framework Core,Entity Framework Migrations,我有ApplicationDbContext,它可以动态地将连接字符串更改为数据库,这取决于用户的库名。因此,对于每个库,我都有自己的数据库。当我创建迁移并应用它们时,它们只与带有默认连接字符串的默认数据库相关,其中没有定义库名称 我如何对所有这些动态创建的数据库进行迁移和应用迁移,这取决于库名称(它们在创建之后就存在,它们是完全定义的和工作的数据库)?如果我正确理解您的意思,您应该实现以下几点: 1) 实现将迁移架构和种子数据的服务。(不管他们在过去做了什么,我还是更喜欢我的实现) 助手
ApplicationDbContext
,它可以动态地将连接字符串更改为数据库,这取决于用户的库名。因此,对于每个库,我都有自己的数据库。当我创建迁移并应用它们时,它们只与带有默认连接字符串的默认数据库相关,其中没有定义库名称
我如何对所有这些动态创建的数据库进行迁移和应用迁移,这取决于库名称(它们在创建之后就存在,它们是完全定义的和工作的数据库)?如果我正确理解您的意思,您应该实现以下几点: 1) 实现将迁移架构和种子数据的服务。(不管他们在过去做了什么,我还是更喜欢我的实现) 助手
public static async Task EnsureSeedData(IServiceProvider serviceProvider)
{
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
// here could be several seed services if necessary
var seedService = scope.ServiceProvider.GetService<ISeedService>();
await seedService.MigrateAsync();
await seedService.SeedAsync();
}
}
种子服务实现
internal sealed class SeedService : ISeedService
{
private readonly InitializeContext _identityContext;
public SeedService(InitializeContext identityContext)
{
_identityContext = identityContext;
}
public async Task MigrateAsync()
{
await _identityContext.Database.MigrateAsync();
}
public async Task SeedAsync()
{
if (_identityContext.AllMigrationsApplied())
{
var strategy = _identityContext.Database.CreateExecutionStrategy();
await strategy.ExecuteAsync(async () =>
{
using (var transaction = await _identityContext.Database.BeginTransactionAsync())
{
// seed data if necessary
transaction.Commit();
}
});
}
}
}
Program.cs文件
public class Program
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
Task.Run(async () =>
{
await SeedData.EnsureSeedData(host.Services);
}).Wait();
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
我希望它能对您有所帮助。您可以使用基于代码的迁移,迭代每个连接字符串:@SteveGreene这不适用于EF Core。是的,EF Core非常原始。你可能会在Startup.cs文件@SteveGreene中找到一个提示。真的,我找不到。你的确切意思是什么?他的startup.cs中有执行迁移的代码。我没有看到太多关于它的文档,但也许它会给你一个提示。请参阅serviceScope.ServiceProvider.GetService().Database.Migrate()附近的行@尤里恩。若它对你们有效并且解决了你们真正的问题,请接受答案。否则,让我知道,我会改进/扩展它。老实说,目前我正在处理另一个问题,无法检查,但我会接受这个答案,让其他用户说更多。
public class Program
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
Task.Run(async () =>
{
await SeedData.EnsureSeedData(host.Services);
}).Wait();
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ISeedService, SeedService>();
services.AddScoped<IDbConfiguration, FakeDbConfiguration>();
services.AddDbContext<InitializeContext>((provider, builder) =>
{
var dbConfiguration = provider.GetService<IDbConfiguration>();
builder.UseSqlServer(dbConfiguration.Connection);
});
// omitted
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// omitted
}
}
internal sealed class FakeDbConfiguration : IDbConfiguration
{
private readonly IConfiguration _configuration;
public FakeDbConfiguration(IConfiguration configuration)
{
_configuration = configuration;
}
// REPLACE THIS PART WITH YOURS IMPLEMENTATION
public string Connection => _configuration["Database:Connection"];