web-dev-qa-db-fra.com

Pas de création initiale avec les migrations Entity Framework

J'essaie de faire en sorte que les migrations de la structure Entity fonctionnent. J'ai activé le code des premières migrations, il a créé un dossier de migration, un fichier de configuration et la table d'historique mig, mais aucune création initiale. Est-ce que je manque une étape? Ceci est une nouvelle base de données créée par EF (4.3.1).

26
newbie_86

Ce comportement n'est pas en place par défaut, mais il vous est facilement disponible sous différentes formes.

  1. Vous pouvez appeler context.Database.CreateIfNotExists(); au démarrage de l'application.

  2. Vous pouvez utiliser l'un des DatabaseInitializers intégrés. L'initialiseur CreateDatabaseIfNotExists est intégré à EntityFramework et doit simplement être ajouté à votre projet.

  3. Vous pouvez créer votre propre initialiseur de base de données personnalisé qui inclut l'option n ° 1 à l'intérieur de lui-même. Exemple: Code First Migrations and initialization

Vous pouvez inclure DatabaseInitializers dans votre projet, soit par code, soit via un fichier de configuration.

Inclure un initialiseur de base de données EntityFramework via le code:

Au démarrage de votre application, vous pouvez configurer DatabaseInitializer comme suit:

System.Data.Entity.Database.SetInitializer<DairyMmmContext>(new System.Data.Entity.CreateDatabaseIfNotExists<DairyMmmContext>());

REMARQUE: ce code a changé plusieurs fois au cours de la vie de entityframework! Cet exemple concerne EF 4.3, la version de production actuelle disponible via Nuget.

Inclure un initialiseur de base de données EntityFramework via un élément de configuration:

<configuration>
  <entityFramework>
    <contexts>
      <context type="MyNamespace.MyEFDataContext, AssemblyName">
        <databaseInitializer
          type="System.Data.Entity.CreateDatabaseIfNotExists`2[[MyNamespace.MyEFDataContext, AssemblyName],
               [MyNamespace.Migrations.Configuration,  AssemblyName]], EntityFramework" />
      </context>
    </contexts>
  </entityFramework>
</configuration>

Vous remarquerez que cela peut être un peu "disgracieux" avec cette configuration. Vous devez remplacer AssemblyName ci-dessus par le nom de l'assembly dans lequel vous conservez vos éléments entityframework, remplacez MyNamespace.MyEFDataContext par le nom complet du contexte de vos données entityframework et remplacez MyNamespace.Migrations.Configuration par le nom complet de votre classe de configuration dossier dans votre projet).

EDIT: édité pour répondre à des commentaires supplémentaires

Une migration est le passage d'une définition de schéma à une autre. La création de la base de données vide n’est pas une migration (mais tout ce qui suit) Il n'y aura pas de fichier source de migration dans votre projet pour simplement créer une base de données vide, effectuée en code par l'initialiseur.

Si vous utilisez déjà l'initialiseur DropCreateDatabaseAlways, vous devriez le faire. Cependant, j’ai remarqué que vous définissiez l’initialiseur dans le code, ce qui signifie qu’un problème de synchronisation risque de se produire (définir l’initialiseur après que votre contexte a déjà dépassé le point d’appeler un initialiseur).

Vous pouvez forcer entityframework à exécuter votre initialiseur à tout moment du code avec context.Database.Initialize(true); (le paramètre est true/false pour forcer l'initialisation quel que soit l'état actuel). Cela déposerait et recréerait votre base de données à chaque fois.

Mais vous pouvez également simplement vous assurer que votre initialiseur est configuré le plus tôt possible dans le cycle de vie de votre application (avant de créer une seule instance de votre contexte).

21
BenSwayne

"Création initiale" n'est pas créé automatiquement! Vous devez créer cela vous-même. Certains tutoriels d'EF sont déroutants et j'ai eu le même malentendu que vous.

Qu'as tu besoin de faire:

-Add-Migration InitialModel

Si vous avez déjà créé vos tables de base de données et votre modèle de domaine, alors: 

-Add-Migration InitialModel -IgnoreChanges

À partir de ce moment, votre code sera synchronisé avec la base de données. Chaque fois que vous modifiez le code, vous pouvez utiliser Add-Migration pour ajouter les modifications à votre base de données.

17
Mosh

L'article/tutoriel ici ici (sur Microsoft.com) Décrit la raison pour laquelle une migration InitialCreate n'existe pas. La migration ne sera ajoutée que si la base de données existe déjà. Sinon, la première migration sera "initialCreate", car il est inutile de créer une migration vers une base de données qui n'existe pas encore ... pas de base de données signifie qu'il n'y a rien à restaurer, lors d'une migration vers le bas.

Voici le paragraphe pertinent:

Exécutez la commande Enable-Migrations dans la console Package Manager Cette commande a ajouté un dossier Migrations à notre projet, ce nouveau dossier contient deux fichiers:

La classe de configuration. Cette classe vous permet de configurer le comportement de Migrations pour votre contexte. Pour cette procédure pas à pas, nous allons simplement utiliser la configuration par défaut . Puisqu'il n'y a qu'un seul contexte Code First dans votre projet, Enable-Migrations a automatiquement renseigné le type de contexte auquel cette configuration s'applique.

Une migration InitialCreate. Cette migration a été générée car Code First avait déjà créé une base de données pour nous, avant d'activer les migrations. Le code de cette migration échafaudée représente les objets déjà créés dans la base de données. Dans notre cas, il s’agit de la table Blog avec les colonnes BlogId et Name. Le nom de fichier comprend un horodatage pour faciliter la commande.

Si la base de données n'avait pas déjà été créée, cette migration InitialCreate n'aurait pas été ajoutée au projet. Au lieu de cela, la première fois que nous appelons Add-Migration, le code permettant de créer ces tables serait échafaudé pour une nouvelle migration.

9
wow0609

Pas sûr que ce soit la même chose, mais j'ai eu un problème similaire. Je pense que mon problème était lié au fait que je n'utilise pas une chaîne de connexion du fichier de configuration pour obtenir ma chaîne de connexion.

En manipulant le projet de démarrage dans la solution et le combo de projet dans la console du gestionnaire de packages, j'ai pu générer cette première migration.

Vérifiez également que vous avez une chaîne de connexions avec le nom de votre classe dbContext afin que le gestionnaire de packages puisse la trouver.

4
jjslagace

Je sais que c'est vieux, mais il n'y a pas de réponse acceptée et j'ai eu le même problème.

L'astuce est la commande Enable-Migrations. Comme indiqué ici il existe une commande Enable-Migrations –EnableAutomaticMigrations. Cela commence les migrations exactement où vous êtes.

Si vous voulez que la première migration soit la création de la base de données, exécutez simplement Enable-Migrations (sans --EnableAutomaticMigrations).

Et n'oubliez pas de définir l'initialiseur:

            Database.SetInitializer(new MigrateDatabaseToLatestVersion<LicenseContext, Configuration>());
0
Krzysztof Skowronek

J'utilise EF 6 RC1 et j'ai rencontré ce problème où ni InitialCreate ni __MigrationHistory n'étaient créés lors de l'exécution de Enable-Migrations.

En fait, juste après la mise à niveau de EF 5 à EF 6, j’ai exécuté Enable-Migrations et, pour une raison quelconque, il a créé une table __MigrationHistory à l’aide du schéma EF 5;.

Mais chaque fois que je supprimais le répertoire Migrations, cela ne créait pas de type InitialCreate ni __MigrationHistory. J'ai essayé de déposer et de recréer la base de données et de redémarrer Visual Studio 2012 sans succès. J'ai abandonné pour la journée et le lendemain matin, j'ai essayé à nouveau - après avoir laissé mon ordinateur reposer pendant environ 8 heures, il a ensuite créé InitialCreate. Je devine qu'il doit y avoir une cache quelque part qui a un très long délai d'attente - quelqu'un? Je suppose également que le redémarrage pourrait effacer le cache, mais je n'ai pas essayé.

Quoi qu'il en soit, il est possible d'utiliser PM> Add-Migration InitialCreate pour effectuer cette étape manuellement.

Quoi qu'il en soit, je n'ai toujours pas reçu de table __MigrationHistory. Apparemment, EF 6 a cessé de le créer lors de la commande Enable-Migrations pour ne le créer que lors de la commande Update-Database. Et comme mon schéma avait déjà été créé à ce moment-là, je devais le supprimer et le recréer manuellement:

PM> Update-Database -TargetMigration:0
PM> Update-Database

Je me suis également arrêté après la première commande pour vérifier l'état de la base de données afin de m'assurer que je mettais à jour la bonne, puisque selon ce résultat , la chaîne de connexion à la base de données est sélectionnée ou générée automatiquement en fonction de la configuration, et à moins qu'elle ne le soit Si vous êtes configuré correctement, rien ne garantit que vous allez accéder à la base de données ou à l’instance de SQL Server que vous souhaitez.

Après avoir exécuté les deux commandes, il a créé une table __MigrationHistory - et ne l'a pas créée en tant que table système (ce que je ne voulais pas vraiment de toute façon), donc tout va bien. Pas exactement le même problème que le PO, mais j'espère que cela sera utile à quelqu'un d'autre.

Références:

0
NightOwl888