Zeu*_*s82 49 c# entity-framework-core asp.net-core
是否可以让我的ASP Core Web API确保使用EF Core将数据库迁移到最新的迁移?我知道这可以通过命令行完成,但我想以编程方式完成.
更新
根据Janshair Khan的回答,我提出了这个助手类:
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using MyWebApi.Models;
namespace MyWebApi
{
public static class DataSeeder
{
public static void SeedData(this IApplicationBuilder app)
{
var context = app.ApplicationServices.GetService<MyContext>();
if (!context.Database.EnsureCreated())
context.Database.Migrate();
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过以下Configure方法调用此方法Startup.cs:
app.SeedData();
Run Code Online (Sandbox Code Playgroud)
Jan*_*han 28
您可以使用
db.Database.EnsureCreated();
Run Code Online (Sandbox Code Playgroud)
让您的数据库与您当前的模型保持同步.如果要启用迁移(如果怀疑后续迁移),请使用
db.Database.Migrate();
Run Code Online (Sandbox Code Playgroud)
并随着时间的推移进行后续迁移.
小智 14
使用以下代码运行迁移
public async void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<YourContext`enter code here`>();
context.Database.Migrate();
}
}
Run Code Online (Sandbox Code Playgroud)
Jas*_*son 14
这在 ASP.NET Core 3.1 中对我有用,只需在Configure方法中注册后将db 上下文作为参数注入现有ConfigureServices方法。
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>(x => x.UseSqlite("Data Source=LocalDatabase.db"));
...
}
Run Code Online (Sandbox Code Playgroud)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext)
{
dataContext.Database.Migrate();
...
}
Run Code Online (Sandbox Code Playgroud)
更多详细信息和完整代码示例链接,请访问https://jasonwatmore.com/post/2019/12/27/aspnet-core-automatic-ef-core-migrations-to-sql-database-on-startup
基于@steamrolla的答案,我将提出以下改进:
public static class EnsureMigration
{
public static void EnsureMigrationOfContext<T>(this IApplicationBuilder app) where T:DbContext
{
var context = app.ApplicationServices.GetService<T>();
context.Database.Migrate();
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您还可以确保迁移不同的上下文,例如,如果您有一个身份数据库。
用法:
app.EnsureMigrationOfContext<context>();
Run Code Online (Sandbox Code Playgroud)
我遵循该IStartupFilter方法来获得迁移任何上下文的通用方法。
public class DataContextAutomaticMigrationStartupFilter<T> : IStartupFilter
where T : DbContext
{
/// <inheritdoc />
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return app =>
{
using (var scope = app.ApplicationServices.CreateScope())
{
scope.ServiceProvider.GetRequiredService<T>().Database.SetCommandTimeout(160);
scope.ServiceProvider.GetRequiredService<T>().Database.Migrate();
}
next(app);
};
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以通过以下方式注册 DataContext 和迁移:
第一个上下文
services.AddDbContext<ConsumerDataContext>(options => options.UseSqlServer(configuration.GetConnectionString("ConsumerConnection")), ServiceLifetime.Transient);
services.AddTransient<IStartupFilter, DataContextAutomaticMigrationStartupFilter<ConsumerDataContext>>();
Run Code Online (Sandbox Code Playgroud)
第二个背景
services.AddDbContext<UserDataContext>(options => options.UseSqlServer(configuration.GetConnectionString("UserConnection")), ServiceLifetime.Transient);
services.AddTransient<IStartupFilter, DataContextAutomaticMigrationStartupFilter<UserDataContext>>();
Run Code Online (Sandbox Code Playgroud)
..等等..
罪魁祸首IStartupFilter是它只允许同步执行代码。对于数据库迁移来说这不是问题,因为我们有同步Migrate()方法。
在Asp core 6中没有StartUp,在以前版本的asp中我们有Configure方法,它允许直接访问ServiceProvider,然后我们可以使用GetServices来获取DBcontext,然后调用Migrate方法。
但现在在 Asp core 6 中。我们应该创建一个范围,然后获取 DBcontext 对象
using (var Scope = app.services.CreateScope())
{
var context = Scope.Services.GetRequireService<DBContext>();
context.Database.Migrate();
}
Run Code Online (Sandbox Code Playgroud)
根据chintan310的回答,这是我迁移数据库的方法。这确保将与数据库相关的任务分离为Program.cs:
public static void Main(string[] args)
{
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetService<AppDbContext>();
context.Database.Migrate();
var seeder = scope.ServiceProvider.GetService<AppSeeder>();
seeder.Seed().Wait();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
host.Run();
}
private static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
Run Code Online (Sandbox Code Playgroud)
此代码适用于.NET core 3.0
using (var scope = app.ApplicationServices.CreateScope())
{
var dbContext = scope.ServiceProvider.GetService<T>();
dbContext.Database.Migrate();
}
Run Code Online (Sandbox Code Playgroud)
使用 C# 7.1 启动 .NET Core 2,您的应用程序可以使用异步Main方法,因此您可以在运行主机之前、在主机完成构建之后调用所有初始化逻辑:
public class Program
{
public static async Task Main(string[] args)
{
//first build
var host = CreateHostBuilder(args).Build();
//initialize
using (var serviceScope = host.Services.CreateScope())
{
var serviceProvider = serviceScope.ServiceProvider;
var isDevelopment =
serviceProvider.GetRequiredService<IWebHostEnvironment>().IsDevelopment();
using var context = serviceProvider.GetRequiredService<AppDbContext>();
if (isDevelopment)
await context.Database.EnsureCreatedAsync();
else
await context.Database.MigrateAsync();
if (isDevelopment)
{
using var userManager =
serviceProvider.GetRequiredService<UserManager<AppUser>>();
await userManager
.CreateAsync(new AppUser { UserName = "dummy", Email = "dummy@dumail.com" },
password: "1234");
}
}
//now run
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Run Code Online (Sandbox Code Playgroud)
Program.cs 在 EF Core 7 中,您可以按照以下方式立即执行var app = builder.Build();此操作:
using (var Scope = app.Services.CreateScope())
{
var context = Scope.ServiceProvider.GetRequiredService<AppDbContext>();
context.Database.Migrate();
}
Run Code Online (Sandbox Code Playgroud)
祝您编码愉快,别忘了投票;)
| 归档时间: |
|
| 查看次数: |
22714 次 |
| 最近记录: |