Předvyplnění dat

Seedování dat je proces naplnění databáze počáteční sadou dat.

V EF Core můžete dosáhnout několika způsoby:

  • Počáteční data modelu
  • Přizpůsobení ruční migrace
  • Logika vlastní inicializace

Počáteční data modelu

Na rozdíl od EF6 se v EF Core dají počáteční data přidružit k typu entity v rámci konfigurace modelu. Migrace EF Core pak můžou automaticky vypočítat, jaké operace vložení, aktualizace nebo odstranění je potřeba použít při upgradu databáze na novou verzi modelu.

Poznámka

Migrace bere v úvahu pouze změny modelu při určování operace, která by se měla provést, aby se počáteční data dostala do požadovaného stavu. Jakékoli změny dat provedených mimo migrace proto můžou být ztraceny nebo způsobit chybu.

V příkladu se nakonfigurují počáteční data pro Blog in OnModelCreating:

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

Pokud chcete přidat entity, které mají relaci, je potřeba zadat hodnoty cizího klíče:

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

Pokud má typ entity nějaké vlastnosti ve stínovém stavu anonymní třídu lze použít k zadání hodnot:

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

Typy vlastněných entit se dají zasadit podobným způsobem:

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

Další kontext najdete v úplném ukázkovém projektu .

Po přidání dat do modelu by se migrace měly použít k použití změn.

Tip

Pokud potřebujete použít migrace jako součást automatizovaného nasazení, můžete vytvořit skript SQL, který se dá před spuštěním zobrazit ve verzi Preview.

Alternativně můžete použít context.Database.EnsureCreated() k vytvoření nové databáze obsahující počáteční data, například pro testovací databázi nebo při použití zprostředkovatele v paměti nebo jakékoli nerelační databáze. Upozorňujeme, že pokud databáze již existuje, EnsureCreated() neaktualizuje schéma ani počáteční data v databázi. U relačních databází byste neměli volat EnsureCreated() , pokud plánujete používat migrace.

Omezení počátečních dat modelu

Tento typ počátečních dat se spravuje migrací a skript pro aktualizaci dat, která jsou již v databázi, je potřeba vygenerovat bez připojení k databázi. To platí pro některá omezení:

  • Hodnotu primárního klíče je potřeba zadat, i když je obvykle vygenerovaná databází. Použije se k detekci změn dat mezi migracemi.
  • Dříve počáteční data budou odebrána, pokud se primární klíč změní jakýmkoli způsobem.

Tato funkce je proto nejužitečnější pro statická data, u která se neočekává změna mimo migrace a nezávisí na ničem jiném v databázi, například PSČ.

Pokud váš scénář obsahuje některou z následujících možností, doporučujeme použít vlastní inicializační logiku popsanou v poslední části:

  • Dočasná data pro testování
  • Data, která závisí na stavu databáze
  • Data, která jsou velká (počáteční data se zaznamenávají ve snímcích migrace a velké objemy dat můžou rychle vést k obrovským souborům a snížení výkonu).
  • Data, která potřebují, aby databáze vygenerovala hodnoty klíčů, včetně entit, které jako identitu používají alternativní klíče
  • Data, která vyžadují vlastní transformaci (která se nezpracují převody hodnot), například některá hashování hesel
  • Data, která vyžadují volání externího rozhraní API, jako jsou role základní identity ASP.NET a vytváření uživatelů

Přizpůsobení ruční migrace

Při přidání migrace se změny zadaných dat HasData transformují na volání , InsertData()UpdateData()a DeleteData(). Jedním ze způsobů, jak obejít některá omezení HasData , je ruční přidání těchto volání nebo vlastních operací do migrace.

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

Logika vlastní inicializace

Jednoduchým a výkonným způsobem, jak provádět počáteční data, je použít DbContext.SaveChanges() před zahájením provádění hlavní logiky aplikace.

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

Upozorňující

Počáteční kód by neměl být součástí normálního spuštění aplikace, protože to může způsobit problémy souběžnosti při spuštění více instancí a zároveň by vyžadovalo, aby aplikace měla oprávnění ke změně schématu databáze.

V závislosti na omezeních nasazení je možné inicializační kód spustit různými způsoby:

  • Místní spuštění inicializační aplikace
  • Nasazení inicializační aplikace s hlavní aplikací, vyvolání rutiny inicializace a zakázání nebo odebrání inicializační aplikace.

Obvykle se to dá automatizovat pomocí profilů publikování.