Comment créer un initialiseur pour créer et migrer une base de données mysql?
J'ai été d'apprendre à utiliser les EF pour une semaine maintenant et je suis coincé sur la question de la création/mise à jour de ma base de données. Je suis en mesure de créer un initialiseur de créer la base de données si elle n'est pas là:
static class Program
{
static void Main()
{
Database.SetInitializer<GumpDatabase>(new GumpDatabaseInitializer());
....
class GumpDatabaseInitializer : CreateDatabaseIfNotExists<GumpDatabase>
{
public GumpDatabaseInitializer()
{
}
protected override void Seed(GumpDatabase context)
{
context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX Name ON Stations (Name)");
//Other stuff
}
}
Ou je peux créer une Configuration pour migrer la db
static class Program
{
static void Main()
{
Database.SetInitializer<GumpDatabase>(new MigrateDatabaseToLatestVersion<GumpDatabase, Configuration>());
....
internal sealed class Configuration : DbMigrationsConfiguration<GumpDatabase>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());
}
protected override void Seed(GumpDatabase context)
{
}
Chaque fonctionne correctement mais je n'ai pas trouvé un moyen de faire les deux. Je peux passer entre les deux initialiseurs par la modification de la SetInitializer appeler, mais si je veux créer la base de données si elle n'est pas là, et aussi de migrer si c'est ce que je fais? Dois-je créer un initialiseur?
Grâce
Modifier basé sur NSGaga réponse
class CreateOrMigrateDatabaseInitializer<TContext, TConfiguration> : CreateDatabaseIfNotExists<TContext>, IDatabaseInitializer<TContext>
where TContext : DbContext
where TConfiguration : DbMigrationsConfiguration<TContext>, new()
{
private readonly DbMigrationsConfiguration _configuration;
public CreateOrMigrateDatabaseInitializer()
{
_configuration = new TConfiguration();
}
public CreateOrMigrateDatabaseInitializer(string connection)
{
Contract.Requires(!string.IsNullOrEmpty(connection), "connection");
_configuration = new TConfiguration
{
TargetDatabase = new DbConnectionInfo(connection)
};
}
void IDatabaseInitializer<TContext>.InitializeDatabase(TContext context)
{
Contract.Requires(context != null, "context");
if (context.Database.Exists())
{
if (!context.Database.CompatibleWithModel(throwIfNoMetadata: false))
{
var migrator = new DbMigrator(_configuration);
migrator.Update();
}
}
else
{
context.Database.Create();
Seed(context);
context.SaveChanges();
}
}
protected virtual void Seed(TContext context)
{
}
}
et
internal sealed class Configuration : DbMigrationsConfiguration<GumpDatabase>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = false;
SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());
}
protected override void Seed(GumpDatabase context)
{
}
}
et
class GumpDatabaseInitializer : CreateOrMigrateDatabaseInitializer<GumpDatabase,Gump.Migrations.Configuration>
{
public GumpDatabaseInitializer()
{
}
protected override void Seed(GumpDatabase context)
{
context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX Name ON Stations (Name)");
context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX Name ON Sequences (Name)");
context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX StationPartNumber ON StationPartNumbers (StationId,PartNumberId)");
}
}
et enfin
static void Main()
{
Database.SetInitializer<GumpDatabase>(new GumpDatabaseInitializer());
source d'informationauteur Matt
Vous devez vous connecter pour publier un commentaire.
Je pense que vous êtes assez bien là - bas, vous pouvez rechercher le code source pour
MigrateDatabaseToLatestVersion
(il est open source http://entityframework.codeplex.com/) - c'est assez simpliste, ce qu'il fait à peu près est de téléphoner à laDbMigrator
- aussi loin que je pouvais voir.Tout ce que vous avez à faire semble est de fusionner les deux - utiliser l'un ou l'autre comme une base, d'ajouter d'autres fonctionnalités - qui devrait fonctionner je pense.
appeler comme ça...
...en fait, le remplacer (car il est générique mise en œuvre) comme vous le faisiez pour
CreateDatabaseIfNotExists
(vous avez juste extra 'param' pour la Configuration) - et il suffit de fournir la "Graine"....et appeler quelque chose comme
EDIT:
Sur la base des commentaires - DbMigrator il ne faut pas courir deux fois. Il vérifie toujours (passe un peu de temps) et fait un 'vide' de mise à jour et se déplace sur. Cependant, juste au cas où si vous souhaitez supprimer et "check" avant d'entrer dans le travail (changement de la pièce similaire ci-dessus)...
(c'est redondant /double-check - on de la si-s devrait être suffisant. Mettez la pause et de voir exactement ce qui se passe, il ne devrait pas obtenir en une fois Db est migré. Comme je l'ai mentionné, fonctionne très bien quand je l'ai tester.
EDIT:
Remplacer l'intérieur de
InitializeDatabase
avec...Cela fonctionne partout (mi-chemin) pas-de semis - si la migration se passe d'abord. Et les migrations être le premier, sinon vous avez des questions.
Vous encore besoin de le faire correctement - c'est l'essentiel si pas tout ce que vous pourriez avoir besoin - mais si tous les problèmes w/MySQL etc., probablement un peu plus de boulot ici.
Remarque: Encore de semis n'a pas à appeler si vous avez une base de données, mais il est vide. Problème, c'est le mélange des deux initialiseurs. De sorte que vous aurez à travailler que ce soit par la mise en œuvre de ce Créer... n'a à l'intérieur (que l'appel que nous ne pouvons pas appeler) ou quelque chose d'autre.
En fait, il devrait être:
parce que si nous avons une migration, qui n'est pas liée à notre db, modèle, par exemple l'insertion d'une ligne dans l'une de nos tables, la migration ne sera pas exécutée.
De faire les deux (semences et de migrer), vous n'avez qu'à utiliser les migrations avec un
MigrateDatabaseToLatestVersion
initialiseur. Lorsque vous activez la migration de votre contexte d'uneConfiguration
classe dérivée deDbMigrationsConfiguration
est créé et vous pouvez remplacer leSemences
méthode de graines de votre base de données. Notez que la base de données peut déjà contenir des graines de données lorsque cette méthode s'exécute mais leAddOrUpdate
méthode d'extension idéalement vous permet de faire des "upserts" dans votre base de données.C'est différent par rapport à la
Seed
méthode de certains de l'autre base de données intitializers où la base de données n'est ensemencé quand il a été initialement créée. Toutefois, lorsque vous utilisez les migrations vous pouvez modifier vos données semences lorsque les modifications de base de données et l'utilisation deMigrateDatabaseToLatestVersion
le rend possible.De combiner l'ensemencement avec les migrations, vous aurez à effectuer les étapes suivantes dans un nouveau projet:
Créer un code-première
DbContext
avec les entités associéesDans le gestionnaire de paquets de la console exécuter la commande
Enable-Migrations
Dans le
Migrations
un dossierConfiguration
classe est générée avec unSeed
méthode. Vous pouvez modifier cette méthode à la graine de votre base de données:Vous avez besoin pour créer un initialiseur de base de données qui en découle
MigrateDatabaseToLatestVersion
:Vous devrez également configurer l'initialiseur, soit par des appels de
Database.SetInitializer(new MyContextInitializer())
lorsque l'application démarre ou dans leApp.config
fichier à l'aide de la<databaseInitializer/>
élément.Dans le constructeur de la générées
Configuration
classe, vous pouvez vous permettre les migrations automatiques:Cependant, dans une équipe, vous préférerez peut-être pas le faire. Dans ce cas, vous devrez créer une première migration (sauf s'il a été créé lorsque vous avez
Enable-Migrations
). Dans le gestionnaire de paquets exécuter la commandeAdd-Migration InitialCreate
. Cela crée de la première migration nécessaire pour créer votre base de données.À ce stade, vous avez une
DbContext
avec les migrations et uneSeed
méthode.Donc pour résumé: Permettre aux migrations, à l'utilisation de la
MigrateDatabaseToLatestVersion
initialiseur et ajouter des graines de données dans leConfiguration
classe qui a été généré lors de migrations ont été activés.Tout MigrateDatabaseToLatestVersion en fait de créer la DB si elle n'existe pas et qui permet à la graine, si vous disposez déjà d'une solution de travail basé sur CreateDatabaseIfNotExists et/ou ne veulent pas compliquer avec les tests pour l'existence de graines de données, vous pouvez utiliser le ci-dessous en héritant d'elle plutôt que de CreateDatabaseIfNotExists:
Ceci est basé sur les réponses précédentes et OP solution propre. Cela devrait fonctionner avec d'autres fournisseurs ainsi, mais je ne l'ai testé avec SQL Server.