¿Habilitar migraciones con contexto en ensamblaje separado?

Tengo un proyecto en el que quiero ejecutar mi update-database pero tengo mis Modelos y Contexto en un proyecto separado.

Si ejecuto enable-migrations obtengo este error: no se encontró ningún tipo de contexto en el ensamblado ‘MyProject’.

Esto es presumiblemente porque mi contexto está en MyProject.MVC.

Si ejecuto enable-migrations contra MyProject.MVC, tengo que agregar un archivo de configuración de la aplicación. No quiero hacer eso porque quiero usar el código en muchos proyectos.

Entonces, ¿puedo ejecutar enable-migrations contra MyProject y de alguna manera decirle que mire en MyProject.MVC para el contexto?

Esto solo funcionará en EF 6, pero hubo una versión que agregó el parámetro -enable-migrations comando -enable-migrations . Al usar este comando, puede hacer lo siguiente:

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

Esto agregará migraciones a su proyecto MyProject usando el contexto en MyProject.MVC . Debe asegurarse de que el proyecto con Migrations tenga una referencia al proyecto con su Contexto, es decir, MyProject referencia a MyProject.MVC

Solo puede ejecutar “Habilitar migraciones” en el proyecto que contiene la clase Contexto de la base de datos.

Su solución contendrá 2 proyectos:

 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"?>   

 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(new MigrateDatabaseToLatestVersion()); 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); } } } } } 

Establecer MyProject.MVC como proyecto de inicio

En el administrador de paquetes, seleccione el proyecto: MyProject.Models

A continuación, ejecute “Habilitar migraciones” para crear la carpeta “Migraciones” en MyProject.Models

Seguido por “Actualizar-Base de datos” -> las migraciones usarán la cadena de conexión en Web.config desde el proyecto de inicio para realizar la migración

Aquí hay una solución:

Agregue una clase en MyProject (el proyecto para migraciones). Haga que esta clase herede el dbcontext (el de MyProject.MVC).

Luego ejecute los comandos de migración EF en MyProject.

Tuve el mismo problema y estoy usando EntityFramework 4.3.1. Parece que EF6 resuelve este problema (de acuerdo con la respuesta de @SOfanatic), pero no quería actualizar a EF6 debido a algunos cambios bruscos (en las Anotaciones de Datos, por ejemplo).

Entonces, lo que hice para resolver esto (y lo que aprendí en el proceso):

  1. Cree una nueva solución (proyecto vacío) y agregue el proyecto donde tiene el modelo para el que desea habilitar las migraciones (en su caso MyProject.MVC). Es posible que deba instalar los paquetes NuGet necesarios antes de que pueda agregar el proyecto existente.

  2. Agregue un archivo de configuración con una cadena de conexión (no se preocupe, esto es solo para engañar al motor de migraciones). Copie su base de datos existente a la carpeta de salida del proyecto modelo (debe ser MVC \ bin \ Debug en su caso). Asegúrese de que la cadena de conexión en el archivo de configuración apunta a esa base de datos:

        
  3. Como tiene una nueva solución, configure su proyecto modelo como un proyecto de inicio (puede eliminar el proyecto predeterminado).

  4. Ejecute el comando enable-migrations en la consola del administrador de paquetes. Debería crear una carpeta Migrations con dos archivos: un Configuration.cs y un archivo InitialCreate.cs con marca de tiempo. Es bueno tener InitialCreate, es por eso que coloca su base de datos existente en la carpeta de salida del proyecto modelo (pero esto es opcional).

  5. Recargue su solución original para que estos cambios se actualicen.

Lo que aprendí (hasta donde yo entiendo):

  1. El motor de migraciones necesita algo que se vea como una conexión válida para funcionar. Estaba creando mi cadena de conexión en el código (en otro proyecto) y eso no funcionó. Acabo de darle al motor de Migrations una cadena de conexión “válida” para que funcione.
  2. Coloque su base de datos donde el motor de migraciones puede encontrarla (también conocida como carpeta de salida del proyecto modelo), por lo que crea un punto de partida para las migraciones. Este punto de partida es básicamente el esquema de su base de datos escrito en la API de migraciones.
  3. Puede restaurar todo a su estado anterior una vez que las migraciones se establecen en su lugar, y funciona bien.
  4. Cada vez que quiera agregar manualmente una migración, debe “engañar” nuevamente al motor de migraciones, al igual que la primera vez. No he intentado con migraciones automáticas, por lo que creo que este enfoque también funciona.

Por cierto, estoy usando una base de datos SQL Server CE 4.0, por lo que algunas cosas sobre la cadena de conexión tienen un pequeño giro en comparación con un estándar SQL Server DB o LocalDB. Además de eso, todo es igual.

Espero que esto sea útil y te dé una idea. Comente si sabe más sobre la forma en que funcionan estas migraciones.