ASP.NET MVC 6 응용 프로그램이 Database.EnsureCreated있고 및 Database.Migrate메서드 를 호출해야 합니다.
하지만 어디로 전화해야합니까?
답변
나는 이것이 중요한 질문이고 잘 대답되어야한다고 생각합니다!
Database.EnsureCreated 란 무엇입니까?
context.Database.EnsureCreated()컨텍스트에 대한 데이터베이스가 존재하는지 확인하는 새로운 EF 핵심 방법입니다. 존재하는 경우 조치가 수행되지 않습니다. 존재하지 않는 경우 데이터베이스와 모든 스키마가 생성되고이 컨텍스트의 모델과 호환되는지 확인합니다.
참고 :
이 방법은 마이그레이션을 사용하여 데이터베이스를 생성하지 않습니다. 또한 생성 된 데이터베이스는 나중에 마이그레이션을 사용하여 업데이트 할 수 없습니다. 관계형 데이터베이스를 대상으로하고 마이그레이션을 사용하는 DbContext.Database.Migrate()경우이 방법을 사용하여 데이터베이스가 생성되고 모든 마이그레이션이 적용되는지 확인할 수 있습니다 .
EF 6으로 어떻게 했습니까?
context.Database.EnsureCreated() EF 6의 아래 나열된 접근 방식과 동일합니다.
-
패키지 관리자 콘솔 :
Enable-Migrations -EnableAutomaticMigrations. 추가 마이그레이션 / 업데이트 데이터베이스.
-
코드에서 :
Database.SetInitializer CreateDatabaseIfNotExists
또는
DbMigrationsConfiguration을 사용하고 AutomaticMigrationsEnabled = true로 설정합니다.
Database.Migrate 란 무엇입니까?
컨텍스트에 대해 보류중인 마이그레이션을 데이터베이스에 적용합니다. 데이터베이스가없는 경우 생성합니다.
EF 6으로 어떻게 했습니까?
context.Database.Migrate() EF 6의 아래 나열된 접근 방식과 동일합니다.
-
패키지 관리자 콘솔 :
업데이트-데이터베이스 -TargetMigration
-
사용자 지정 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();
}
답변
일반적으로는 다음과 같이 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를 사용하고 있습니다.
답변
