it-swarm.com.de

Migrationen mit Kontext in separater Assembly aktivieren?

Ich habe ein Projekt, gegen das ich meinen update-database ausführen möchte, aber ich habe meine Modelle und den Kontext in einem separaten Projekt.

Wenn ich enable-migrations starte, erhalte ich folgende Fehlermeldung: In der Assembly 'MyProject' wurde kein Kontexttyp gefunden.

Dies liegt vermutlich daran, dass sich mein Kontext in MyProject.MVC befindet.

Wenn ich enable-migrations gegen MyProject.MVC starte, muss ich eine App-Konfigurationsdatei hinzufügen. Ich möchte das nicht tun, da ich den Code in vielen Projekten verwenden möchte.

Kann ich enable-migrations gegen MyProject ausführen und ihm irgendwie mitteilen, dass er in MyProject.MVC nach dem Kontext suchen soll?

61
Jon

Dies funktioniert nur in EF 6, aber es gab ein release , das den -ContextProjectName -Parameter zum -enable-migrations-Befehl hinzufügte. Mit diesem Befehl können Sie Folgendes tun:

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

Dadurch werden Migrationen zu Ihrem MyProject-Projekt hinzugefügt, indem Sie den Kontext in MyProject.MVC..__ verwenden. Sie müssen sicherstellen, dass das Projekt mit den Migrationen einen Verweis auf das Projekt mit Ihrem Kontext enthält, dh MyProject-Referenzen MyProject.MVC

98
SOfanatic

Sie dürfen "Enable-Migrations" nur in dem Projekt ausführen, das die Database Context-Klasse enthält.

Ihre Lösung enthält 2 Projekte:

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);
                }
            }
        }
    }
}

Legen Sie MyProject.MVC als Startprojekt fest

Wählen Sie im Paket-Manager Projekt aus: MyProject.Models

Führen Sie dann "Enable-Migrations" aus, um den Ordner "Migrations" in MyProject.Models zu erstellen

Gefolgt von "Update-Database" -> Migrationen verwenden die Verbindungszeichenfolge in Web.config aus dem Startprojekt, um die Migration durchzuführen

12
cronixis

Hier ist eine Problemumgehung:

Fügen Sie eine Klasse in MyProject hinzu (das Projekt für Migrationen). Lassen Sie diese Klasse den dbcontext erben (den in MyProject.MVC).

Führen Sie dann die EF-Migrationsbefehle auf MyProject aus.

3
Jan Bizub

Ich hatte das gleiche Problem und verwende EntityFramework 4.3.1. Es scheint, dass EF6 dieses Problem löst (entsprechend der Antwort von @SOfanatic), aber ich wollte nicht auf EF6 aktualisieren, da einige Änderungen vorgenommen wurden (z. B. in den DataAnnotations).

Also, was ich getan habe, um das zu lösen (und was ich dabei gelernt habe):

  1. Erstellen Sie eine neue Lösung (leeres Projekt) und fügen Sie das Projekt hinzu, für das Sie das Modell haben, für das Sie Migrationen aktivieren möchten (in Ihrem Fall MyProject.MVC). Möglicherweise müssen Sie die erforderlichen NuGet-Pakete dafür installieren, bevor Sie das vorhandene Projekt hinzufügen können.

  2. Fügen Sie eine Konfigurationsdatei mit einer Verbindungszeichenfolge hinzu (keine Sorge, dies dient nur dazu, die Migrations-Engine zu überlisten). Kopieren Sie Ihre vorhandene Datenbank in den Ausgabeordner des Modellprojekts (in Ihrem Fall sollte dies MVC\bin\Debug sein). Stellen Sie sicher, dass die Verbindungszeichenfolge in der Konfigurationsdatei auf diese Datenbank verweist:

    <connectionStrings>
        <add name="MyDB" providerName="System.Data.SqlServerCe.4.0" connectionString="DataSource=|DataDirectory|\MyDB.sdf"/>
      </connectionStrings>
    
  3. Da Sie sich in einer neuen Lösung befinden, legen Sie Ihr Modellprojekt als Startprojekt fest (Sie können das Standardprojekt entfernen).

  4. Führen Sie den Befehl enable-migrations in der Paket-Manager-Konsole aus. Es sollte einen Migrationsordner mit zwei Dateien erstellen: einer Configuration.cs-Datei und einer InitialCreate.cs-Datei mit Zeitstempel. Es ist schön, InitialCreate zu haben. Deshalb legen Sie Ihre vorhandene Datenbank in den Ausgabeordner des Modellprojekts (dies ist jedoch optional).

  5. Laden Sie Ihre ursprüngliche Lösung neu, damit diese Änderungen aktualisiert werden.

Was ich gelernt habe (soweit ich es verstehe):

  1. Das Migrationsmodul benötigt etwas, das wie eine gültige Verbindung aussieht. Ich habe meine Verbindungszeichenfolge in Code erstellt (in einem anderen Projekt) und das hat nicht funktioniert. Ich habe der Migrations-Engine nur eine "gültige" Verbindungszeichenfolge gegeben, damit sie funktioniert.
  2. Platzieren Sie Ihre Datenbank dort, wo die Migrations-Engine sie finden kann (auch als Ausgabeordner des Modellprojekts bezeichnet), um einen Ausgangspunkt für Migrationen zu schaffen. Dieser Ausgangspunkt ist im Wesentlichen Ihr Datenbankschema, das in der Migrations-API geschrieben ist.
  3. Sie können nach dem Einrichten der Migrationen alles auf Ihren vorherigen Zustand zurücksetzen und es funktioniert einwandfrei.
  4. Jedes Mal, wenn Sie eine Migration manuell hinzufügen möchten, müssen Sie die Migrations-Engine erneut "überlisten", genau wie beim ersten Mal. Ich habe es nicht mit automatischen Migrationen versucht, ich denke, dieser Ansatz funktioniert auch.

Im Übrigen verwende ich eine SQL Server CE 4.0-Datenbank, sodass einige Dinge über die Verbindungszeichenfolge im Vergleich zu einer Standard-SQL Server-Datenbank oder einer lokalen Datenbank eine kleine Abweichung haben. Abgesehen davon ist alles gleich.

Hoffe, das ist hilfreich und gibt Ihnen einen Einblick. Bitte kommentieren Sie, wenn Sie mehr über die Funktionsweise dieser Migrationen wissen.

0
Hannish