Ответ 1
Вы можете вызвать context.Database.Migrate()
в Startup.cs
например:
using (var context = new MyContext(...))
{
context.Database.Migrate();
}
Есть ли какой-либо код для автоматической миграции в Entity Framework core
code first
в основном проекте asp.net?
Я делаю это просто в MVC4/5, добавляя
Database.SetInitializer(new MigrateDatabaseToLatestVersion<AppDbContext, MyProject.Migrations.Configuration>());
public Configuration() {
AutomaticMigrationsEnabled = true;
}
Это экономит время, когда сущности изменяются
Вы можете вызвать context.Database.Migrate()
в Startup.cs
например:
using (var context = new MyContext(...))
{
context.Database.Migrate();
}
EF core не поддерживает automatic migrations
. Поэтому вы должны сделать это вручную.
С точки зрения автоматических миграций как функции мы не планируя внедрить его в EF Core, поскольку опыт показал, что кодовая база миграции - более управляемый подход.
Вы можете прочитать полную историю здесь: Не выполнять автоматические миграции
Так они делают это в IdentityServer4 http://identityserver.io
public void ConfigureServices(IServiceCollection services)
{
var connectionString = Configuration.GetConnectionString("DefaultConnection");
var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// this will do the initial DB population
InitializeDatabase(app);
}
private void InitializeDatabase(IApplicationBuilder app)
{
using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
{
scope.ServiceProvider.GetRequiredService<ApplicationDbContext>().Database.Migrate();
scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
...
}
}
Автоматическая миграция не поддерживается в EF Core. Миграцию надо создавать руками. Чтобы автоматически применить все существующие миграции вручную, необходимо добавить следующий код в DbContext:
public sealed class MyDbContext : DbContext
{
private static readonly bool[] _migrated = { false };
public MyDbContext( DbContextOptions<MyDbContext> options ) : base( options )
{
if ( !_migrated[0] )
lock ( _migrated )
if ( !_migrated[0] )
{
Database.Migrate(); // apply all migrations
_migrated[0] = true;
}
}
}
Это не элегантно, но работает.
Обновление для EFCore 2.1:
public class Program
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<MyDbContext>();
context.Database.Migrate(); // apply all migrations
SeedData.Initialize(services); // Insert default data
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
После документации Microsoft
https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro
Если вы используете инъекцию зависимостей, сначала вам необходимо установить статический класс Data/DbInitializer.cs и добавить следующий код:
public static class DbInitializer
{
public static void Initialize(ApplicationDbContext context)
{
context.Database.Migrate();
// Add Seed Data...
}
}
Обратите внимание, что вы также можете добавить данные семени.
Затем в файле Program.cs добавьте следующий код
public static void Main(string[] args)
{
var host = BuildWebHost(args);
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var environment = services.GetRequiredService<IHostingEnvironment>();
if (!environment.IsDevelopment())
{
var context = services.GetRequiredService<ApplicationDbContext>();
DbInitializer.Initialize(context);
}
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while seeding the database.");
}
}
host.Run();
}
В моем случае я проверяю среду, чтобы убедиться, что я в разработке, поэтому я могу контролировать миграцию/обновления. Однако в производстве я хочу, чтобы они были автоматическими для непрерывной интеграции. Как отмечали другие, это, вероятно, не лучшая практика, но на небольших проектах она отлично работает.
Мой рабочий код миграции Asp Net Core 2.0.7.
// startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// configure app
SeedData.Initialize(app.ApplicationServices);
}
// dbInitializer.cs
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var serviceScope = serviceProvider.CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
// auto migration
context.Database.Migrate();
// Seed the database.
InitializeUserAndRoles(context);
}
}
private static void InitializeUserAndRoles(ApplicationDbContext context)
{
// init user and roles
}
}
Вы можете вызвать Database.Migrate()
в конструкторе контекста БД.
мой лучший совет - не использовать автоматическую миграцию. Всегда лучше добавлять миграции вручную, а также избегать массовой миграции и придерживаться наилучшей практики для ручной миграции.
автоматическая миграция не является волшебным инструментом, и будет несколько случаев, когда вы захотите добавить некоторые дополнительные изменения в перенос. Вы выполняете только с помощью ручной миграции.
Чтобы включить миграцию, введите "enable-migrations" в консоли диспетчера пакетов
Таким образом, вы будете иметь полный контроль над обновлением или понижением базы данных, а также легко отслеживать миграцию.
Всего три простых шага в консоли диспетчера пакетов.
1) add-migrations [некоторое имя для вашей миграции]
2) для изменений создаются миграции, вы их просматриваете, а также можете внесите в него изменения
3) обновленная база данных теперь завершена.
обработка миграции менее болезненна!