[英]Create and apply migrations for all databases in Entity Framework Core
I have ApplicationDbContext
, which dynamically change connection string to database, which depends on user's library name.我有ApplicationDbContext
,它动态地将连接字符串更改为数据库,这取决于用户的库名称。 So, for each library, I have it's own database.所以,对于每个图书馆,我都有自己的数据库。 When I'm creating migrations and apply them, they are related only to default database with default connection string, where no library name defined.当我创建迁移并应用它们时,它们仅与具有默认连接字符串的默认数据库相关,其中没有定义库名称。
How can I make and apply migrations to all this databases, that dynamically created, that depends on library name (they exist after creation, they are fully defined and working databases)?我如何对所有这些动态创建的数据库进行迁移并将其应用到依赖于库名称的数据库(它们在创建后存在,它们是完全定义和工作的数据库)?
If I understood you properly, you should implement the following:如果我理解正确,您应该执行以下操作:
1) Implement Service that will migrate your schema and seed data. 1) 实施将迁移您的架构和种子数据的服务。 (despite what they did in the latest version , I still prefer my implementation) (尽管他们在最新版本中做了什么,我仍然更喜欢我的实现)
Helper帮手
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();
}
}
ISeedService Interface种子服务接口
internal interface ISeedService
{
Task MigrateAsync();
Task SeedAsync();
}
SeedService Implementation种子服务实现
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 file程序.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>();
}
2) Register context and related services in DI, which will allow dynamically retrieve connection string. 2) 在 DI 中注册上下文和相关服务,这将允许动态检索连接字符串。 There are several ways to do it, my implementation is not the best one, so it's up to you.有几种方法可以做到,我的实现不是最好的,所以这取决于你。
Startup.cs file启动.cs文件
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
}
}
DbConfiguration file. Db 配置文件。
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"];
I hope it help you.我希望它能帮助你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.