Permettre les Migrations avec Contexte Dans L'assemblage séparé?

j'ai un projet contre lequel je veux lancer mon update-database mais j'ai mes modèles et mon contexte dans un projet séparé.

si j'exécute enable-migrations j'obtiens cette erreur: Aucun type de contexte n'a été trouvé dans l'Assemblée 'MyProject'.

c'est probablement parce que mon contexte est dans MyProject.MVC.

si j'exécute enable-migrations contre MyProject.MVC je dois ajouter un fichier de configuration de l'application. Je ne veux pas le faire comme je veux utiliser le code à travers de nombreux projets.

alors je peux lancer enable-migrations contre MyProject et lui dire de regarder dans MyProject.MVC pour le contexte?

60
demandé sur Matteo Mosca 2013-08-08 16:59:30

4 réponses

cela ne fonctionnera que dans EF 6, mais il y avait un release qui a ajouté le paramètre -ContextProjectName à la commande -enable-migrations . En utilisant cette commande, vous pouvez faire ce qui suit:

enable-migrations -ContextProjectName MyProject.MVC -StartUpProjectName MyProject.MVC 
-ContextTypeName MyProject.MVC.MyContextFolder.MyContextName -ProjectName MyProject

cela ajoutera des migrations à votre projet MyProject en utilisant le contexte dans le MyProject.MVC . Vous devez vous assurer que le projet avec les Migrations a une référence au projet avec votre contexte, i.e., MyProject références MyProject.MVC

94
répondu SOfanatic 2013-08-08 14:33:04

vous ne pouvez exécuter" Enable-Migrations " que dans le projet contenant la classe Context De La base de données.

votre solution contiendra 2 projets:

1) MyProject.Models
    |- Migrations
        |- 201401061557314_InitialCreate.cs
        |- Configuration.cs
    |- MyContext.cs
    |- App.config (no connection string)



App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>



2) MyProject.MVC
        |- Filters
            |- InitializeSimpleMembershipAttribute.cs



InitializeSimpleMembershipAttribute.cs

namespace MyProject.MVC.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
    {
        private static SimpleMembershipInitializer _initializer;
        private static object _initializerLock = new object();
        private static bool _isInitialized;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Ensure ASP.NET Simple Membership is initialized only once per app start
            LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
        }

        private class SimpleMembershipInitializer
        {
            public SimpleMembershipInitializer()
            {
                try
                {
                    Database.SetInitializer<MyContext>(new MigrateDatabaseToLatestVersion<MyContext, MyProject.Model.Migrations.Configuration>());

                    using (var context = new MyContext())
                    {
                        context.Database.Initialize(force: true);
                        if (!context.Database.Exists())
                        {
                            // Create the SimpleMembership database without Entity Framework migration schema
                            ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                        }
                    }

                    WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
                }
            }
        }
    }
}

Set MyProject.MVC comme projet de démarrage

dans Gestionnaire de paquets, sélectionnez Projet: MyProject.Modèles

exécute ensuite" Enable-Migrations "pour créer le dossier" Migrations " dans MyProject.Modèles

suivi de" Update-Database " - > migrations utilisera la chaîne de connexion dans le Web.config à partir d'un démarrage de projet pour effectuer la migration

11
répondu cronixis 2014-01-16 16:53:25

voici une solution:

ajouter une classe dans MyProject(le projet pour les migrations). Faites que cette classe hérite de la dbcontext(celle de MyProject.MVC).

lancez ensuite les commandes de migration EF sur MyProject.

3
répondu Jan Bizub 2017-02-10 16:44:48

j'ai eu le même problème, et j'utilise le cadre D'Entité4.3. 1. Il semble que EF6 résolve ce problème (selon la réponse de @SOfanatic) mais je ne voulais pas passer à EF6 à cause de quelques changements de rupture (dans les annotations de données, par exemple).

alors, ce que j'ai fait pour résoudre ceci (et ce que j'ai appris dans le processus):

  1. créez une nouvelle solution (projet vide) et ajoutez le projet où vous avez le modèle que vous voulez pour activer les migrations pour (dans votre cas, MyProject.MVC). Vous devrez peut-être installer les paquets NuGet nécessaires avant de pouvoir ajouter le projet existant.

  2. Ajouter un fichier de configuration avec une chaîne de connexion (ne vous inquiétez pas, c'est seulement pour tromper le moteur de migrations). Copiez votre base de données existante dans le dossier de sortie du projet model (devrait être MVC\bin\Debug dans votre cas). Assurez-vous que la chaîne de connexion dans le fichier de configuration pointe vers cette base de données.:

    <connectionStrings>
        <add name="MyDB" providerName="System.Data.SqlServerCe.4.0" connectionString="DataSource=|DataDirectory|\MyDB.sdf"/>
      </connectionStrings>
    
  3. puisque vous êtes dans une nouvelle solution, définissez votre projet modèle comme un projet de démarrage (vous pouvez supprimer le projet par défaut).

  4. lancez la commande enable-migrations dans la console du gestionnaire de paquets. Il devrait créer un dossier Migrations avec deux fichiers: une Configuration.cs and a timestampen InitialCreate.cs fichier. C'est bien d'avoir le premier rêve, c'est pourquoi vous avez mis votre base de données existante dans le dossier de sortie du projet de modèle (mais c'est facultatif).

  5. Rechargez votre solution originale afin que ces modifications soient mises à jour.

Ce que j'ai appris (comme je le comprends):

  1. le moteur de migration a besoin de quelque chose qui ressemble à une connexion valide pour fonctionner. Je créais ma chaîne de connexion en code (dans un autre projet) et cela ne travail. J'ai juste donné au moteur de migration une chaîne de connexion "valide" pour le faire fonctionner.
  2. Placez votre base de données là où le moteur de migration peut la trouver (dossier de sortie du projet de modèle aka) afin qu'elle crée un point de départ pour les migrations. Ce point de départ est essentiellement votre schéma de base de données écrit dans l'API migrations.
  3. vous pouvez tout restaurer à votre état précédent une fois que les migrations sont mises en place, et cela fonctionne bien.
  4. Chaque fois que vous voulez ajouter manuellement une migration, vous devez "tromper" le moteur de migrations à nouveau, comme la première fois. Je n'ai pas essayé avec les migrations automatiques, par je suppose que cette approche fonctionne aussi bien.

par ailleurs, j'utilise une base de données SQL Server CE 4.0, donc certaines choses au sujet de la chaîne de connexion ont une petite torsion par rapport à une base de données SQL Server Standard ou LocalDB. En plus de cela, tout de même.

j'Espère que cela est utile et vous donne un aperçu. S'il vous plaît commenter si vous en savez plus sur la façon dont ces migrations fonctionnent.

0
répondu Hannish 2013-10-26 11:09:34