J'utilise l'approche Entity Framework Code First avec AutomaticMigrationsEnabled = true
:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DbContext, MigrateDBConfiguration>());
//////////////////////////////////
public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<DbContext>
{
public MigrateDBConfiguration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
}
La première exécution du projet crée la base de données et les tables comme prévu. Après avoir changé mon modèle en ajoutant ou en supprimant des champs, j'ai exécuté Add-Migration
. La classe Migration a été générée mais après l'exécution du projet, cette exception se produit:
Une exception de type "System.InvalidOperationException" s'est produite dans EntityFramework.dll mais n'a pas été gérée dans le code utilisateur
Informations supplémentaires: Le modèle qui soutient le contexte "DBContext" a changé depuis la création de la base de données.
EDIT: Selon les conseils de la réponse de arturo menchaca J'ai changé mon code comme ceci:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DBContext, MigrateDBConfiguration<DBContext>>());
...
Après la modification, cette exception se produit:
Il existe déjà un objet nommé "MyTable" dans la base de données.
Comment puis-je appliquer ma migration de base de données?
Enfin, j'ai trouvé une solution à mon problème. J'appelle cette méthode à chaque démarrage d'application:
public void InitializeDatabase(DataAccessManager context)
{
if (!context.Database.Exists() || !context.Database.CompatibleWithModel(false))
{
var configuration = new DbMigrationsConfiguration();
var migrator = new DbMigrator(configuration);
migrator.Configuration.TargetDatabase = new DbConnectionInfo(context.Database.Connection.ConnectionString, "System.Data.SqlClient");
var migrations = migrator.GetPendingMigrations();
if (migrations.Any())
{
var scriptor = new MigratorScriptingDecorator(migrator);
var script = scriptor.ScriptUpdate(null, migrations.Last());
if (!string.IsNullOrEmpty(script))
{
context.Database.ExecuteSqlCommand(script);
}
}
}
}
Migrations automatiques signifie que vous n'avez pas besoin d'exécuter la commande add-migration
Pour vos modifications dans les modèles, mais vous devez exécuter la commande update-database
Manuellement.
Si Migrations automatiques est activé lorsque vous appelez update-database
, S'il y a des modifications en attente dans vos modèles, une migration "automatique" sera ajoutée et la base de données sera mise à jour.
Si vous voulez que votre base de données soit mise à jour sans avoir besoin d'appeler la commande update-database
, Vous pouvez ajouter la méthode Database.SetInitializer(...)
dans OnModelCreating()
sur votre contexte, comme ceci:
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, MigrateDBConfiguration>());
}
...
}
public class MigrateDBConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<MyContext>
{
...
Notez que vous devez déclarer DbMigrationsConfiguration
et MigrateDatabaseToLatestVersion
avec votre contexte réel, pas le DbContext
par défaut.
Si vous avez modifié vos entités, vous devez d'abord exécuter add-migration
pour créer le script de migration.
Après cela, dans votre Global.asax
vous devez avoir un code comme celui-ci
var configuration = new MyProject.Configuration();
var migrator = new System.Data.Entity.Migrations.DbMigrator(configuration);
migrator.Update();
chaque fois que vous exécutez votre projet asp.net, il vérifie si vous avez une nouvelle migration à exécuter et à exécuter update-database
automatiquement pour vous.