Data SeedingData Seeding

Seeding von Daten ist der Prozess für das Auffüllen einer Datenbank mit einem anfänglichen Satz von Daten.Data seeding is the process of populating a database with an initial set of data.

Es gibt verschiedene Möglichkeiten, die dies in EF Core erreicht werden kann:There are several ways this can be accomplished in EF Core:

  • Seed-Daten des ModellsModel seed data
  • Manuelle Migration AnpassungManual migration customization
  • Benutzerdefinierte InitialisierungslogikCustom initialization logic

Seed-Daten des ModellsModel seed data

Hinweis

Dieses Feature ist neu in EF Core 2.1.This feature is new in EF Core 2.1.

Im Gegensatz zu kann in EF6 in EF Core seeding von Daten mit einem Entitätstyp als Teil der Modellkonfiguration verknüpft sein.Unlike in EF6, in EF Core, seeding data can be associated with an entity type as part of the model configuration. EF Core Migrationen bestimmen dann automatisch, welche INSERT-, UPDATE- oder DELETE-Operationen beim Upgrade der Datenbank auf eine neue Version des Datenmodells angewendet werden müssen.Then EF Core migrations can automatically compute what insert, update or delete operations need to be applied when upgrading the database to a new version of the model.

Hinweis

Migrationen berücksichtigt nur modelländerungen beim bestimmen, welcher Vorgang ausgeführt werden soll, um die Seed-Daten in den gewünschten Zustand zu erhalten.Migrations only considers model changes when determining what operation should be performed to get the seed data into the desired state. Daher können Änderungen an den Daten, die außerhalb von Migrationen durchgeführt getrennt werden, oder führen zu einem Fehler.Thus any changes to the data performed outside of migrations might be lost or cause an error.

Dadurch wird beispielsweise startwertdaten für konfiguriert eine Blog in OnModelCreating:As an example, this will configure seed data for a Blog in OnModelCreating:

modelBuilder.Entity<Blog>().HasData(new Blog {BlogId = 1, Url = "http://sample.com"});

Um Entitäten hinzuzufügen, die eine Beziehung die Fremdschlüsselwerte müssen angegeben werden:To add entities that have a relationship the foreign key values need to be specified:

modelBuilder.Entity<Post>().HasData(
    new Post() { BlogId = 1, PostId = 1, Title = "First post", Content = "Test 1" });

Wenn der Entitätstyp alle Eigenschaften, die Shadow-Status, die eine anonyme Klasse verwendet werden kann aufweist, um die Werte bereitzustellen:If the entity type has any properties in shadow state an anonymous class can be used to provide the values:

modelBuilder.Entity<Post>().HasData(
    new { BlogId = 1, PostId = 2, Title = "Second post", Content = "Test 2" });

Der eigenen Entität, die Typen, die auf ähnliche Weise ausgeführt werden können:Owned entity types can be seeded in a similar fashion:

modelBuilder.Entity<Post>().OwnsOne(p => p.AuthorName).HasData(
    new { PostId = 1, First = "Andriy", Last = "Svyryd" },
    new { PostId = 2, First = "Diego", Last = "Vega" });

Finden Sie unter den vollständigen Beispielprojekt für weiteren Kontext.See the full sample project for more context.

Nachdem die Daten, dem Modell hinzugefügt wurde Migrationen sollte verwendet werden, um die Änderungen zu übernehmen.Once the data has been added to the model, migrations should be used to apply the changes.

Tipp

Wenn Sie zum Anwenden von Migrationen als Teil einer automatisierten Bereitstellung benötigen können Sie erstellen Sie ein SQL­Skript können, die vor der Ausführung eine Vorschau angezeigt werden.If you need to apply migrations as part of an automated deployment you can create a SQL script that can be previewed before execution.

Alternativ können Sie context.Database.EnsureCreated() zum Erstellen einer neuen Datenbank, die die Seed-Daten, z. B. für eine Testdatenbank oder bei Verwendung von in-Memory-Anbieter oder eine nicht-Relation-Datenbank enthält.Alternatively, you can use context.Database.EnsureCreated() to create a new database containing the seed data, for example for a test database or when using the in-memory provider or any non-relation database. Beachten Sie, dass bei die Datenbank bereits vorhanden ist, EnsureCreated() wird weder die Schema noch Seed-Daten in der Datenbank aktualisiert.Note that if the database already exists, EnsureCreated() will neither update the schema nor seed data in the database. Sie sollten nicht für relationale Datenbanken aufrufen EnsureCreated() , wenn Sie Migrationen verwenden möchten.For relational databases you shouldn't call EnsureCreated() if you plan to use Migrations.

Einschränkungen des Modells Seed-DatenLimitations of model seed data

Diese Art von Seed-Daten wird durch Migrationen verwaltet, und das Skript zum Aktualisieren der Daten, die bereits in der Datenbank ist ohne Verbindung zur Datenbank generiert werden muss.This type of seed data is managed by migrations and the script to update the data that's already in the database needs to be generated without connecting to the database. Diese erzwingt einige Einschränkungen:This imposes some restrictions:

  • Wert des Primärschlüssels muss angegeben werden, auch wenn es in der Regel von der Datenbank generiert wird.The primary key value needs to be specified even if it's usually generated by the database. Er wird zum Erkennen von datenänderungen zwischen Migrationen verwendet werden.It will be used to detect data changes between migrations.
  • Zuvor werden per Seeding hinzugefügte Daten entfernt werden, wenn der Primärschlüssel in keiner Weise geändert wird.Previously seeded data will be removed if the primary key is changed in any way.

Aus diesem Grund eignet sich diese Funktion am besten für statische Daten, die ist nicht dazu gedacht, die außerhalb von Migrationen zu ändern, und hängt nicht alles in der Datenbank, z. B. Postleitzahlen.Therefore this feature is most useful for static data that's not expected to change outside of migrations and does not depend on anything else in the database, for example ZIP codes.

Wenn Ihr Szenario eine der folgenden enthält wird empfohlen, die angepasste Initialisierung von Logik, die im vorherigen Abschnitt beschrieben zu verwenden:If your scenario includes any of the following it is recommended to use custom initialization logic described in the last section:

  • Temporäre Daten für TestsTemporary data for testing
  • Daten, die abhängig von DatenbankstatusData that depends on database state
  • Daten, die Schlüsselwerte generiert werden, von der Datenbank, einschließlich der Entitäten, die alternativen Schlüssel als Identität verwendet.Data that needs key values to be generated by the database, including entities that use alternate keys as the identity
  • Daten, die eine benutzerdefinierte Transformation erfordert, (, erfolgt nicht durch Wert Konvertierungen), z. B. eine Kennwort-hashingData that requires custom transformation (that is not handled by value conversions), such as some password hashing
  • Daten, die Aufrufe an externe API, z.B. ASP.NET Core Identity-Rollen und Benutzer erstellen erfordernData that requires calls to external API, such as ASP.NET Core Identity roles and users creation

Manuelle Migration AnpassungManual migration customization

Wenn eine Migration die Änderungen an den Daten, die mit angegebenen hinzugefügt wird HasData werden in Aufrufe an transformiert InsertData(), UpdateData(), und DeleteData().When a migration is added the changes to the data specified with HasData are transformed to calls to InsertData(), UpdateData(), and DeleteData(). Eine Möglichkeit, arbeiten umgehungslösungen zu einigen der Einschränkungen der HasData besteht darin, diese Aufrufe manuell hinzufügen oder benutzerdefinierte Vorgänge zur Migration stattdessen.One way of working around some of the limitations of HasData is to manually add these calls or custom operations to the migration instead.

migrationBuilder.InsertData(
    table: "Blogs",
    columns: new[] { "Url" },
    values: new object[] { "http://generated.com" });

Benutzerdefinierte InitialisierungslogikCustom initialization logic

Eine einfache und leistungsstarke Möglichkeit zum seeding von Daten ausführen ist die Verwendung DbContext.SaveChanges() vor der hauptanwendung Logik ihrer Ausführung beginnt.A straightforward and powerful way to perform data seeding is to use DbContext.SaveChanges() before the main application logic begins execution.

using (var context = new DataSeedingContext())
{
    context.Database.EnsureCreated();

    var testBlog = context.Blogs.FirstOrDefault(b => b.Url == "http://test.com");
    if (testBlog == null)
    {
        context.Blogs.Add(new Blog { Url = "http://test.com" });
    }
    context.SaveChanges();
}

Warnung

Der seedingcode muss nicht Teil der normal-app-Ausführung, wie dies von Parallelitätsproblemen führen kann, wenn mehrere Instanzen ausgeführt werden und müsste auch die app keine Berechtigung zum Ändern des Datenbankschemas.The seeding code should not be part of the normal app execution as this can cause concurrency issues when multiple instances are running and would also require the app having permission to modify the database schema.

Je nach den Einschränkungen der Bereitstellung kann der Initialisierungscode auf unterschiedliche Weise ausgeführt werden:Depending on the constraints of your deployment the initialization code can be executed in different ways:

  • Lokales Ausführen der app für die InitialisierungRunning the initialization app locally
  • Die Initialisierung-app mit der Haupt-app, die Initialisierungsroutine aufrufen, und deaktivieren, oder entfernen die Initialisierung-app bereitstellen.Deploying the initialization app with the main app, invoking the initialization routine and disabling or removing the initialization app.

Dies kann in der Regel mit automatisiert werden Veröffentlichungsprofile.This can usually be automated by using publish profiles.