我有ApplicationDbContext
,它会动态地将连接字符串更改为数据库,这取决于用户的库名。所以,对于每个库,我都拥有自己的数据库。当我创建迁移并应用它们时,它们仅与默认连接字符串的默认数据库相关,其中没有定义库名称。
如何创建和应用迁移到动态创建的所有数据库,这些数据库取决于库名称(它们在创建后存在,它们是完全定义的和工作的数据库)?
答案 0 :(得分:2)
如果我对您的理解正确,则应该执行以下操作:
1)实施服务,该服务将迁移您的架构和种子数据。 (尽管他们在latest version中做了什么,但我仍然更喜欢实施)
助手
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接口
internal interface ISeedService
{
Task MigrateAsync();
Task SeedAsync();
}
SeedService实施
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>();
}
2)在DI中注册上下文和相关服务,这将允许动态检索连接字符串。有几种方法可以实现,我的实现不是最好的方法,所以这取决于您。
Startup.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文件。
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"];
希望对您有帮助。