Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP-Core在启动时迁移EF Core SQL DB_C#_Asp.net Core_Entity Framework Core - Fatal编程技术网

C# ASP-Core在启动时迁移EF Core SQL DB

C# ASP-Core在启动时迁移EF Core SQL DB,c#,asp.net-core,entity-framework-core,C#,Asp.net Core,Entity Framework Core,是否可以让我的ASP Core Web API确保使用EF Core将数据库迁移到最新的迁移?我知道这可以通过命令行完成,但我想通过编程来完成。您可以使用 db.Database.EnsureCreated(); 使数据库与当前模型保持同步。如果要启用迁移(如果怀疑后续迁移),请使用 db.Database.Migrate(); 并随时间推移放置后续迁移。文档中关于调用db.Database.EnsureCreated()的注释: 请注意,此API不使用迁移来创建数据库。在里面 此外,创建的

是否可以让我的ASP Core Web API确保使用EF Core将数据库迁移到最新的迁移?我知道这可以通过命令行完成,但我想通过编程来完成。

您可以使用

db.Database.EnsureCreated();
使数据库与当前模型保持同步。如果要启用迁移(如果怀疑后续迁移),请使用

db.Database.Migrate();

并随时间推移放置后续迁移。

文档中关于调用
db.Database.EnsureCreated()的注释:

请注意,此API不使用迁移来创建数据库。在里面 此外,创建的数据库以后无法使用更新 迁移。如果您以关系数据库为目标并使用 迁移时,可以使用DbContext.Database.Migrate()方法 确保创建了数据库并应用了所有迁移

您可能只想调用
db.Database.Migrate()


上述声明来源的评论。

根据@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();
    }
}
publicstaticclass加密
{
公共静态上下文(此IAApplicationBuilder应用程序),其中T:DbContext
{
var context=app.ApplicationServices.GetService();
Migrate();
}
}
这样,您还可以确保不同上下文的迁移,例如,如果您有一个标识数据库

用法:

app.EnsureMigrationOfContext<context>();
app.EnsureMigrationOfContext();

使用下面的代码在以下位置运行迁移

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();
    }
}
公共异步无效配置(IApplicationBuilder应用程序、IHostingEnvironment环境、iLogger工厂)
{
使用(var serviceScope=app.ApplicationServices.GetRequiredService().CreateScope())
{
var context=serviceScope.ServiceProvider.GetService();
Migrate();
}
}

根据chintan310的回答,以下是我如何迁移数据库。这确保了将数据库相关任务分离为
程序.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();
publicstaticvoidmain(字符串[]args)
{
var host=BuildWebHost(args);
使用(var scope=host.Services.CreateScope())
{
var services=scope.ServiceProvider;
尝试
{
var context=services.GetService();
Migrate();
var seeder=scope.ServiceProvider.GetService();
播种机。播种()。等待();
}
捕获(例外情况除外)
{
var logger=services.GetRequiredService();
logger.LogError(例如,“在数据库中发生错误”);
}
}
host.Run();
}
私有静态IWebHost BuildWebHost(字符串[]args)=>
WebHost.CreateDefaultBuilder(args)
.UseStartup()
.Build();

我这样做是为了使用EF Core 2.1.2和SQL Server以编程方式进行迁移,基于之前在此处和“”上的回答:

Startup.cs

使用Microsoft.AspNetCore.Builder;
使用Microsoft.AspNetCore.Hosting;
使用Microsoft.Extensions.Configuration;
使用Microsoft.Extensions.DependencyInjection;
使用Microsoft.EntityFrameworkCore;
名称空间MyApp
{
公营创业
{
//…(仅包括相关代码)。。。
public void配置服务(IServiceCollection服务)
{
services.AddDbContext(选项=>
options.UseSqlServer(Configuration.GetConnectionString(“MyAppContext”));
// ...
}
公共无效配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
使用(var serviceScope=app.ApplicationServices.CreateScope())
{
var context=serviceScope.ServiceProvider.GetService();
Migrate();
}
// ...
}
}
}

使用此代码的项目是。

这是对先前创建扩展方法的答案的轻微更正。它修复了按编写方式抛出的错误

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace MyApp.Extensions
{
    public static class IApplicationBuilderExtensions
    {
        public static void SyncMigrations<T>(this IApplicationBuilder app) where T : DbContext
        {
            using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
            {
                var context = serviceScope.ServiceProvider.GetService<DbContext>();
                context.Database.Migrate();
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用Microsoft.AspNetCore.Builder;
使用Microsoft.EntityFrameworkCore;
使用Microsoft.Extensions.DependencyInjection;
命名空间MyApp.Extensions
{
公共静态类IAApplicationBuilderExtensions
{
公共静态void同步迁移(此IAApplicationBuilder应用程序),其中T:DbContext
{
使用(var serviceScope=app.ApplicationServices.GetRequiredService().CreateScope())
{
var context=serviceScope.ServiceProvider.GetService();
Migrate();
}
}
}
}

此代码适用于.NET core 3.0

 using (var scope = app.ApplicationServices.CreateScope())
 {
     var dbContext = scope.ServiceProvider.GetService<T>();
     dbContext.Database.Migrate();
 }
使用(var scope=app.ApplicationServices.CreateScope())
{
var dbContext=scope.ServiceProvider.GetService();
dbContext.Database.Migrate();
}

这对我在ASP.NET Core 3.1中很有效,在
ConfigureServices
方法中注册数据库上下文后,将其作为参数注入
Configure
方法

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<DataContext>(x => x.UseSqlite("Data Source=LocalDatabase.db"));

    ...
}

有关完整代码示例的更多详细信息和链接,请访问

我遵循了
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);
        };
    }
}
公共类DataContextAutomaticMiggerationStartupFilter:IStartupFilter
其中T:DbContext
{
/// 
公共操作配置(下一步操作)
{
返回应用=>
{
使用(var scope=app.ApplicationServices.CreateScope())
{
scope.ServiceProvider.GetRequiredService().Database.SetCommandTimeout(160);
scope.ServiceProvider.GetRequiredService().Database.Migrate();
}
下一步(应用程序);
};
}
}
现在,我们可以通过以下方式注册DataContext和迁移:

第一上下文

 services.AddDbContext<ConsumerDataContext>(options => options.UseSqlServer(configuration.GetConnectionString("ConsumerConnection")), ServiceLifetime.Transient);
    services.AddTransient<IStartupFilter, DataContextAutomaticMigrationStartupFilter<ConsumerDataContext>>();
services.AddDbContext<ConsumerDataContext>(options => options.UseSqlServer(configuration.GetConnectionString("ConsumerConnection")), ServiceLifetime.Transient); services.AddTransient<IStartupFilter, DataContextAutomaticMigrationStartupFilter<ConsumerDataContext>>();
services.AddDbContext<UserDataContext>(options => options.UseSqlServer(configuration.GetConnectionString("UserConnection")), ServiceLifetime.Transient);
services.AddTransient<IStartupFilter, DataContextAutomaticMigrationStartupFilter<UserDataContext>>();