Teilen über


Automatische Code First-Migrationen

Mit automatischen Migrationen können Sie Code First-Migrationen verwenden, ohne für jede von Ihnen vorgenommene Änderung eine Codedatei in Ihrem Projekt zu haben. Nicht alle Änderungen können automatisch angewendet werden – Spaltenumbenennungen erfordern beispielsweise die Verwendung einer codebasierten Migration.

Hinweis

In diesem Artikel wird davon ausgegangen, dass Ihnen bekannt ist, wie Sie Code First-Migrationen in Basisszenarien verwenden. Wenn nicht, sollten Sie Code First-Migrationen lesen, bevor Sie fortfahren.

Empfehlung für Teamumgebungen

Sie können automatische und codebasierte Migrationen miteinander kombinieren, aber dies wird in Teamentwicklungsszenarien nicht empfohlen. Wenn Sie Teil eines Teams von Entwicklern sind, die Quellcodeverwaltung verwenden, sollten Sie entweder rein automatische Migrationen oder rein codebasierte Migrationen verwenden. Angesichts der Einschränkungen der automatischen Migrationen empfehlen wir die Verwendung von codebasierten Migrationen in Teamumgebungen.

Erstellen eines Ausgangsmodells und einer Ausgangsdatenbank

Bevor Sie Migrationen verwenden können, benötigen Sie ein Projekt und ein Code First-Modell. In dieser exemplarischen Vorgehensweise werden die kanonischen Modelle Blog und Post verwendet.

  • Erstellen Sie eine neue MigrationsAutomaticDemo-Konsolenanwendung
  • Fügen Sie dem Projekt die neueste Version des NuGet-Pakets EntityFramework hinzu.
    • Wählen Sie Tools > Bibliotheks-Paket-Manger > Paket-Manager-Konsole aus.
    • Führen Sie den Befehl Install-Package EntityFramework aus.
  • Fügen Sie eine Model.cs-Datei mit dem unten aufgeführten Code hinzu. Mit diesem Code wird eine einzelne Blog-Klasse, die das Domänenmodell bildet, und eine BlogContext-Klasse, die den EF Code First-Kontext darstellt, definiert.
    using System.Data.Entity;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity.Infrastructure;

    namespace MigrationsAutomaticDemo
    {
        public class BlogContext : DbContext
        {
            public DbSet<Blog> Blogs { get; set; }
        }

        public class Blog
        {
            public int BlogId { get; set; }
            public string Name { get; set; }
        }
    }
  • Mit dem Modell können Sie nun auf die Daten zugreifen. Aktualisieren Sie die Program.cs-Datei mit dem folgenden Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace MigrationsAutomaticDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var db = new BlogContext())
                {
                    db.Blogs.Add(new Blog { Name = "Another Blog " });
                    db.SaveChanges();

                    foreach (var blog in db.Blogs)
                    {
                        Console.WriteLine(blog.Name);
                    }
                }

                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
        }
    }
  • Führen Sie Ihre Anwendung aus, und Sie werden sehen, dass eine MigrationsAutomaticCodeDemo.BlogContext-Datenbank für Sie erstellt wird.

    Database LocalDB

Aktivieren von Migrationen

Im Folgenden erfahren Sie, wie Sie weitere Änderungen am Modell vornehmen.

  • Fügen Sie der Blog-Klasse eine URL-Eigenschaft hinzu.
    public string Url { get; set; }

Wenn Sie zu diesem Zeitpunkt die Anwendung erneut ausführen würden, erhielten Sie die Ausnahme „InvalidOperationException“ mit folgendem Text: Das Unterstützungsmodell des Kontexts „BlogContext“ wurde seit der Erstellung der Datenbank geändert. Sie können Code First-Migrationen verwenden, um die Datenbank zu aktualisieren (http://go.microsoft.com/fwlink/?LinkId=238269).

Beginnen Sie daher mit der Verwendung von Code First-Migrationen. Da wir automatische Migrationen verwenden möchten, geben wir den Switch –EnableAutomaticMigrations an.

  • Führen Sie den Befehl Enable-Migrations –EnableAutomaticMigrations in der Paket-Manager-Konsole aus. Dieser Befehl hat unserem Projekt einen Ordner Migrationen hinzugefügt. Dieser neue Ordner enthält eine Datei:

  • Die Dateikonfigurationsklasse: Mit dieser Klasse können Sie das Verhalten von Migrationen für den Kontext konfigurieren. Verwenden Sie für diese exemplarische Vorgehensweise die Standardkonfiguration. Da in Ihrem Projekt nur ein einzelner Code First-Kontext vorhanden ist, wurde der Kontexttyp, der für diese Konfiguration gilt, automatisch von „Enable-Migrations“ ausgefüllt.

 

Ihre erste automatische Migration

Code First-Migrationen verfügt über zwei primäre Befehle, die Sie im Folgenden kennenlernen werden:

  • Add-Migration erstellt den Entwurf für die nächste Migration basierend auf Änderungen, die Sie seit dem Erstellen der letzten Migration an Ihrem Modell vorgenommen haben.
  • Update-Database übernimmt alle ausstehenden Migrationen für die Datenbank.

Wir werden die Verwendung von Add-Migration vermeiden (es sei denn, wir benötigen es wirklich) und uns darauf konzentrieren, Code First-Migrationen die Änderungen automatisch berechnen und anwenden zu lassen. Lassen Sie uns Update-Database verwenden, um Code First-Migrationen zu veranlassen, die Änderungen an unser Modell (die neue Blog.Url-Eigenschaft) an die Datenbank zu pushen.

  • Führen Sie in der Paket-Manager-Konsole den Befehl Update-Database aus.

Die Datenbank MigrationsAutomaticDemo.BlogContext ist jetzt aktualisiert und enthält in der Blogs-Tabelle die Spalte URL.

 

Ihre zweite automatische Migration

Lassen Sie uns eine weitere Änderung vornehmen, und lassen Sie Code First-Migrationen automatisch die Änderungen für uns an die Datenbank pushen.

  • Fügen Sie zudem eine neue Post-Klasse hinzu.
    public class Post
    {
        public int PostId { get; set; }
        [MaxLength(200)]
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public Blog Blog { get; set; }
    }
  • Fügen Sie anschließend der Blog-Klasse eine Posts-Sammlung hinzu, die das andere Ende der Beziehung zwischen Blog und Post bilden soll.
    public virtual List<Post> Posts { get; set; }

Verwenden Sie jetzt Update-Datenbank, um die Datenbank auf den neuesten Stand zu bringen. Geben Sie dieses Mal das Flag –Verbose an, damit das SQL angezeigt wird, mit dem Code First-Migrationen ausgeführt wird.

  • Führen Sie in der Paket-Manager-Konsole den Befehl Update-Database –Verbose aus.

Hinzufügen einer codebasierten Migration

Sehen wir uns jetzt etwas an, für das wir möglicherweise eine codebasierte Migration verwenden möchten.

  • Lassen Sie uns der Blog-Klasse eine Eigenschaft Rating hinzufügen
    public int Rating { get; set; }

Wir konnten einfach Update-Database ausführen, um diese Änderungen an die Datenbank zu pushen. Wir fügen jedoch eine Non-Nullable-Spalte Blogs.Rating hinzu. Wenn bereits Daten in der Tabelle vorhanden sind, wird der CLR-Standardwert des Datentyps für die neue Spalte zugewiesen („Rating“ ist ein Integer, also wäre dies 0). Damit die vorhandenen Spalten der Blogs-Tabelle mit einem vernünftigen Rating-Wert beginnen, geben Sie den Standardwert 3 an. Lassen Sie uns den Befehl Add-Migration verwenden, um diese Änderung in eine codebasierte Migration zu schreiben, damit wir sie bearbeiten können. Mit dem Add-Migration-Befehl können Sie diesen Migrationen einen Namen geben, lassen Sie uns unsere Migration AddBlogRating nennen.

  • Führen Sie in der Paket-Manager-Konsole den Befehl Add-Migration AddBlogRating aus.
  • Im Ordner Migrationen haben wird nun eine neue AddBlogRating-Migration. Dem Dateinamen der Migration ist ein Zeitstempel vorangestellt, um die Sortierung zu erleichtern. Lassen Sie uns den generierten Code bearbeiten, um einen Standardwert von 3 für Blog.Rating anzugeben (Zeile 10 im folgenden Code)

Die Migration verfügt auch über eine CodeBehind-Datei, die einige Metadaten erfasst. Mit diesen Metadaten können Code First-Migrationen die automatischen Migrationen replizieren, die wir vor dieser codebasierten Migration durchgeführt haben. Dies ist wichtig, wenn ein anderer Entwickler unsere Migrationen ausführen möchte, oder wenn es an der Zeit ist, unsere Anwendung bereitzustellen.

    namespace MigrationsAutomaticDemo.Migrations
    {
        using System;
        using System.Data.Entity.Migrations;

        public partial class AddBlogRating : DbMigration
        {
            public override void Up()
            {
                AddColumn("Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3));
            }

            public override void Down()
            {
                DropColumn("Blogs", "Rating");
            }
        }
    }

Die Migration ist nun fertig bearbeitet. Aktualisieren Sie daher die Datenbank mit Update-Database.

  • Führen Sie in der Paket-Manager-Konsole den Befehl Update-Database aus.

Zurück zu automatischen Migrationen

Wir sind jetzt frei, zu automatischen Migrationen für unsere einfacheren Änderungen zurückzukehren. Code First-Migrationen werden sich um die Durchführung der automatischen und codebasierten Migrationen in der richtigen Reihenfolge kümmern, basierend auf den Metadaten, die sie in der CodeBehind-Datei für jede codebasierte Migration speichern.

  • Lassen Sie uns unserem Modell eine Post.Abstract-Eigenschaft hinzufügen
    public string Abstract { get; set; }

Jetzt können wir Update-Database verwenden, um Code First-Migrationen zu veranlassen, diese Änderung mithilfe einer automatischen Migration an die Datenbank zu pushen.

  • Führen Sie in der Paket-Manager-Konsole den Befehl Update-Database aus.

Zusammenfassung

In dieser exemplarischen Vorgehensweise haben Sie gesehen, wie Sie mithilfe von automatischen Migrationen Modelländerungen an die Datenbank pushen können. Außerdem haben Sie gesehen, wie Sie zwischen automatischen Migrationen ein Gerüst für codebasierte Migrationen erstellen und ausführen, wenn Sie mehr Kontrolle benötigen.