[asp.net] Database.EnsureCreated 및 Database.Migrate를 어디에서 어떻게 호출합니까?

ASP.NET MVC 6 응용 프로그램이 Database.EnsureCreated있고 및 Database.Migrate메서드 를 호출해야 합니다.

하지만 어디로 전화해야합니까?



답변

나는 이것이 중요한 질문이고 잘 대답되어야한다고 생각합니다!

Database.EnsureCreated 란 무엇입니까?

context.Database.EnsureCreated()컨텍스트에 대한 데이터베이스가 존재하는지 확인하는 새로운 EF 핵심 방법입니다. 존재하는 경우 조치가 수행되지 않습니다. 존재하지 않는 경우 데이터베이스와 모든 스키마가 생성되고이 컨텍스트의 모델과 호환되는지 확인합니다.

참고 :
이 방법은 마이그레이션을 사용하여 데이터베이스를 생성하지 않습니다. 또한 생성 된 데이터베이스는 나중에 마이그레이션을 사용하여 업데이트 할 수 없습니다. 관계형 데이터베이스를 대상으로하고 마이그레이션을 사용하는 DbContext.Database.Migrate()경우이 방법을 사용하여 데이터베이스가 생성되고 모든 마이그레이션이 적용되는지 확인할 수 있습니다 .

EF 6으로 어떻게 했습니까?

context.Database.EnsureCreated() EF 6의 아래 나열된 접근 방식과 동일합니다.

  1. 패키지 관리자 콘솔 :

    Enable-Migrations -EnableAutomaticMigrations. 추가 마이그레이션 / 업데이트 데이터베이스.

  2. 코드에서 :

    Database.SetInitializer CreateDatabaseIfNotExists

또는

DbMigrationsConfiguration을 사용하고 AutomaticMigrationsEnabled = true로 설정합니다.

Database.Migrate 란 무엇입니까?

컨텍스트에 대해 보류중인 마이그레이션을 데이터베이스에 적용합니다. 데이터베이스가없는 경우 생성합니다.

EF 6으로 어떻게 했습니까?

context.Database.Migrate() EF 6의 아래 나열된 접근 방식과 동일합니다.

  1. 패키지 관리자 콘솔 :

    업데이트-데이터베이스 -TargetMigration

  2. 사용자 지정 DbMigrationsConfiguration 사용 :

    AutomaticMigrationsEnabled = false; 또는 DbMigrator와 함께.

결론 :

마이그레이션을 사용하는 경우 context.Database.Migrate(). 마이그레이션을 원하지 않고 빠른 데이터베이스 (일반적으로 테스트 용) 만 원한다면 context.Database.EnsureCreated () / EnsureDeleted ()를 사용하십시오.


답변

James P와 Bassam Alugili가 제공 한 정보를 사용하여 결국이 코드 줄을 클래스 ( Startup.cs ) 의 Configure메서드에 추가했습니다 .Startup

using (var scope =
  app.ApplicationServices.CreateScope())
using (var context = scope.ServiceProvider.GetService<MyDbContext>())
    context.Database.Migrate();


답변

앞서 언급 한 것처럼 Rowan Miller의 다음 내용을 읽어야 합니다 .

EnsureCreated마이그레이션을 완전히 우회하고 스키마를 생성합니다. 마이그레이션과 혼합 할 수 없습니다. EnsureCreated매번 데이터베이스를 삭제하고 다시 생성해도 괜찮은 테스트 또는 신속한 프로토 타이핑을 위해 설계되었습니다. 마이그레이션을 사용 중이고 앱 시작시 자동으로 적용되도록하려면 context.Database.Migrate()대신 사용할 수 있습니다 .

대답에 따르면 여기 다음 항목에 추가 Globals.EnsureDatabaseCreated();해야합니다 Startup.cs.

시작 기능 Startup.cs의 :

public Startup(IHostingEnvironment env)
{
    // Set up configuration sources.
    var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddEnvironmentVariables();

    if (env.IsDevelopment())
    {
        // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
            builder.AddApplicationInsightsSettings(developerMode: true);
    }
    Configuration = builder.Build();
    Globals.Configuration = Configuration;
    Globals.HostingEnvironment = env;
    Globals.EnsureDatabaseCreated();
}

그리고 다음 Globals.EnsureDatabaseCreated()과 같이 정의하십시오 .

public static void EnsureDatabaseCreated()
    {
        var optionsBuilder = new DbContextOptionsBuilder();
        if (HostingEnvironment.IsDevelopment()) optionsBuilder.UseSqlServer(Configuration["Data:dev:DataContext"]);
        else if (HostingEnvironment.IsStaging()) optionsBuilder.UseSqlServer(Configuration["Data:staging:DataContext"]);
        else if (HostingEnvironment.IsProduction()) optionsBuilder.UseSqlServer(Configuration["Data:live:DataContext"]);
        var context = new ApplicationContext(optionsBuilder.Options);
        context.Database.EnsureCreated();

        optionsBuilder = new DbContextOptionsBuilder();
        if (HostingEnvironment.IsDevelopment()) optionsBuilder.UseSqlServer(Configuration["Data:dev:TransientContext"]);
        else if (HostingEnvironment.IsStaging()) optionsBuilder.UseSqlServer(Configuration["Data:staging:TransientContext"]);
        else if (HostingEnvironment.IsProduction()) optionsBuilder.UseSqlServer(Configuration["Data:live:TransientContext"]);
        new TransientContext(optionsBuilder.Options).Database.EnsureCreated();
    }

사용하려면 여기 또는 여기를context.Database.Migrate() 참조 하십시오 .


답변

일반적으로는 다음과 같이 DbContext종속성 주입 컨테이너에 추가됩니다 Startup.ConfigureServices().

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add DbContext to the injection container
        services.AddDbContext<MyDbContext>(options =>
                options.UseSqlServer(
                    this.Configuration.GetConnectionString("DefaultConnection")));
    }
}

그러나 IServiceCollection는 서비스 제공 업체로 작동하지 않으며은 현재 범위 이전에DbContext 주입 컨테이너에 등록되지 않았기 때문에 (Startup.ConfigureServices ) 되지 않았으므로 여기서 종속성 주입을 통해 컨텍스트에 액세스 할 수 없습니다.

Henk Mollema는 여기 에서 시작하는 동안 서비스를 수동으로 해결하는 방법에 대해 설명 하지만 다음과 같이 언급합니다.

서비스를 수동으로 해결 (서비스 로케이터라고도 함)하는 것은 일반적으로 안티 패턴으로 간주됩니다 . [그리고] 가능한 한 피해야합니다.

Henk는 또한 Startup생성자의 종속성 주입이 매우 제한적이며에서 구성된 서비스를 포함하지 않기 Startup.ConfigureServices()때문에 DbContext 사용이 앱의 나머지 부분에서 사용되는 주입 컨테이너를 통해 가장 쉽고 적절하다고 언급합니다.

런타임의 호스팅 서비스 공급자는 , ( 3.0 이전 버전) 및 .NET Startup과 같은 특정 서비스를 클래스 생성자에 삽입 할 수 있습니다 . 후자는 호스팅 계층에 의해 구축 된 인스턴스이며 애플리케이션을 시작하는 데 필요한 필수 서비스 만 포함합니다.IConfigurationIWebHostEnvironmentIHostingEnvironmentILoggerFactoryIServiceProvider

주문 전화에서 Database.EnsureCreated()또는 Database.Migrate(), 우리가 할 수있는, 그리고에 자동으로 DbContext의 결의를 갖고 싶어 Startup.Configure()우리의 구성 서비스는 DI를 통해 사용할 수있는 곳 :

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add DbContext to the injection container
        services.AddDbContext<MyDbContext>(options =>
                options.UseSqlServer(
                    this.Configuration.GetConnectionString("DefaultConnection")));
    }

    public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, MyDbContext context)
    {
        if (env.IsDevelopment())
        {
            context.Database.EnsureCreated();
            //context.Database.Migrate();
        }
    }
}

로 기억하십시오 바삼 Alugili의 대답 것을 EF 코어 문서에서 참조 Database.EnsureCreated()Database.Migrate()하나 개의 보장하지만 기존 마이그레이션이 필요한 경우 생성 된 데이터베이스에 적용되기 때문에 함께 사용되는 것은 아니다. 다른 하나는 데이터베이스가 존재하는지 확인하고 그렇지 않은 경우 DbContext컨텍스트에서 Fluent API를 통해 수행 된 시드를 포함하여 를 반영하는 데이터베이스를 생성합니다 .


답변

또한 컨텍스트의 생성자에서 이것을 호출하면 성능 저하를 볼 수 있습니다 EnsureCreated. setup.cs 유틸리티로 이동 한 후 응답 시간이 크게 향상되었습니다.

참고 : EFC 및 UWP를 사용하고 있습니다.


답변