59

Ho un progetto su cui voglio eseguire il mio update-database ma ho i miei Modelli e Contesto in un progetto separato.Abilita le migrazioni con contesto in Assieme separato?

Se corro enable-migrations Ho ricevuto questo errore: Nessun tipo di contesto è stato trovato nell'assembly "MyProject".

Questo è presumibilmente perché il mio contesto è in MyProject.MVC.

Se eseguo enable-migrations su MyProject.MVC, devo aggiungere un file di configurazione dell'app. Non voglio farlo perché voglio usare il codice su molti progetti.

Così posso eseguire enable-migrations contro MyProject e in qualche modo dirlo di cercare in MyProject.MVC per il contesto?

+0

PM> enable-migrations -projectname yourproject –

risposta

90

Questo funzionerà solo in EF 6, ma c'era un release che ha aggiunto il parametro -ContextProjectName al comando -enable-migrations. Utilizzando questo comando è possibile effettuare le seguenti operazioni:

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

Questo aggiungerà migrazioni al progetto MyProject utilizzando il contesto nel MyProject.MVC. È necessario assicurarsi che il progetto con le migrazioni ha un riferimento al progetto con il proprio contesto, vale a dire, MyProject riferimenti MyProject.MVC

+6

Questo è il modo corretto per farlo, sono sorpreso @Jon non ha accettato come risposta. – JARRRRG

+0

Questo ha fatto il lavoro per me. Grazie @ SOfanatic – Alaor

+0

Se 'MyProject' ha un contesto per' MyProject.MVC', non creerebbe una dipendenza circolare? – Arithmomaniac

0

Ho avuto lo stesso problema, e sto usando EntityFramework 4.3.1. Sembra che EF6 risolva questo problema (in base alla risposta di @ SOfanatic) ma non volevo eseguire l'aggiornamento a EF6 a causa di alcune modifiche irrisolte (ad esempio, in DataAnnotations).

Allora, che cosa ho fatto per risolvere questo (e quello che ho imparato nel processo):

  1. creare una nuova soluzione (progetto vuoto) e aggiungere il progetto in cui si ha il modello che si desidera attivare migrazioni per (nel tuo caso MyProject.MVC). Potrebbe essere necessario installare i pacchetti NuGet richiesti per questo prima di poter aggiungere il progetto esistente.

  2. Aggiungere un file di configurazione con una stringa di connessione (non preoccuparti, questo è solo per ingannare il motore di migrazione). Copia il tuo database esistente nella cartella di output del progetto del modello (nel tuo caso dovrebbe essere MVC \ bin \ Debug). Assicurarsi che la stringa di connessione nei punti di file di configurazione per tale database:

    <connectionStrings> 
        <add name="MyDB" providerName="System.Data.SqlServerCe.4.0" connectionString="DataSource=|DataDirectory|\MyDB.sdf"/> 
        </connectionStrings> 
    
  3. Dal momento che ci si trova in una nuova soluzione, impostare il vostro progetto modello come un progetto di avvio (è possibile rimuovere il progetto di default).

  4. Eseguire il comando enable-migrations nella console del gestore pacchetti. Dovrebbe creare una cartella Migrations con due file: un file Configuration.cs e un file InitialCreate.cs con data/ora. È bello avere InitialCreate, ecco perché inserisci il tuo database esistente nella cartella di output del progetto del modello (ma questo è facoltativo).

  5. Ricarica la tua soluzione originale in modo che queste modifiche vengano aggiornate.

Quello che ho imparato (per quanto ho capito):

  1. Il motore migrazioni ha bisogno di qualcosa che assomiglia a una connessione valida al lavoro. Stavo creando la mia stringa di connessione in codice (in un altro progetto) e questo non ha funzionato. Ho appena dato al motore Migrations una stringa di connessione "valida" per farlo funzionare.
  2. Inserire il database in cui può trovarlo il motore di migrazione (ovvero la cartella di output del progetto del modello) in modo da creare un punto di partenza per le migrazioni. Questo punto di partenza è fondamentalmente lo schema del database scritto nell'API di migrazione.
  3. È possibile ripristinare tutto allo stato precedente una volta impostate le migrazioni e funziona correttamente.
  4. Ogni volta che si desidera aggiungere manualmente una migrazione, è necessario "ingannare" nuovamente il motore di migrazione, proprio come la prima volta. Non ho provato con le migrazioni automatiche, credo che questo approccio funzioni pure.

A titolo esimo, sto usando un database di SQL Server CE 4.0, per cui alcune cose circa la stringa di connessione hanno un po 'di torsione rispetto ad un DB SQL Server standard o LocalDB. Oltre a ciò, è tutto uguale.

Spero che questo sia utile e ti dia qualche informazione. Si prega di commentare se si conosce meglio il modo in cui queste migrazioni funzionano.

11

È possibile eseguire solo "Abilita-Migrazioni" nel progetto che contiene la classe Contesto database.

La soluzione conterrà 2 progetti:

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 come progetto di avvio

Nel package manager, selezionare progetto: MyProject.Models

Quindi eseguire "Attiva-Migrazioni" per creare Cartella "Migrazioni" in MyProject.Models

Seguito da "Aggiornamento database" -> migrazione s utilizzerà stringa di connessione nel web.config dal progetto di avvio per eseguire la migrazione

2

Ecco una soluzione:

aggiungere una classe in MyProject (il progetto per le migrazioni). Rendi questa classe ereditare il dbcontext (quello in MyProject.MVC).

Quindi eseguire i comandi di migrazione EF su MyProject.

Problemi correlati