Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az adatbevetés egy adatbázis kezdeti adatkészlettel való feltöltésének folyamata.
Ez az EF Core-ban többféleképpen is elvégezhető:
-
Konfigurációs beállítások – adatbevetés (
UseSeeding) - egyéni inicializálási logika
-
modell által felügyelt adatok (
HasData) - manuális migrálás testreszabása
Konfigurációs beállítások UseSeeding és UseAsyncSeeding metódusok
Az EF 9 bevezette UseSeeding és UseAsyncSeeding módszereket, amelyek kényelmes módot biztosítanak az adatbázis kezdeti adatokkal való bevetésére. Ezek a módszerek az egyéni inicializálási logika használatának élményét hivatottak javítani (az alábbiakban ismertetjük). Egy egyértelmű helyet biztosítanak, ahol az összes adatbevetési kód elhelyezhető. Ezenkívül a UseSeeding és UseAsyncSeeding metódusok kódját a migrálási zárolási mechanizmus védi, az egyidejűségi problémák megelőzése érdekében.
Az új vetési módszereket EnsureCreated művelet, Migrate és dotnet ef database update parancs részeként hívjuk meg, még akkor is, ha nincsenek modellmódosítások, és nem alkalmaztak áttelepítést.
Borravaló
A UseSeeding és a UseAsyncSeeding használata az adatbázis kezdeti adatokkal való üzembe helyezésének ajánlott módja az EF Core használatakor.
Ezeket a metódusokat a beállítási lehetőségekkonfigurációs lépésében lehet beállítani. Íme egy példa:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFDataSeeding;Trusted_Connection=True;ConnectRetryCount=0")
.UseSeeding((context, _) =>
{
var testBlog = context.Set<Blog>().FirstOrDefault(b => b.Url == "http://test.com");
if (testBlog == null)
{
context.Set<Blog>().Add(new Blog { Url = "http://test.com" });
context.SaveChanges();
}
})
.UseAsyncSeeding(async (context, _, cancellationToken) =>
{
var testBlog = await context.Set<Blog>().FirstOrDefaultAsync(b => b.Url == "http://test.com", cancellationToken);
if (testBlog == null)
{
context.Set<Blog>().Add(new Blog { Url = "http://test.com" });
await context.SaveChangesAsync(cancellationToken);
}
});
Jegyzet
UseSeeding
/
UseAsyncSeedinga rendszer meghívja az áttelepítések alkalmazása során EnsureCreated/EnsureCreatedAsync és után (például/MigrateMigrateAsync , dotnet ef database updateés migrálási kötegeket).
Az EF Core-eszközök és -csomagok jelenleg a szinkron delegáltra támaszkodnak, ezért mindig implementálhatók UseSeeding akkor is, ha az alkalmazás általában aszinkron API-kat használ.
Üzembe helyezési viselkedés
UseSeeding és UseAsyncSeeding csak akkor fut, ha az EF Core adatbázis-inicializálási vagy migrálási műveletet hajt végre. Ennek megfelelően válasszon ki egy üzembehelyezési mechanizmust:
| Operation | Meghívott vetésmeghatalmazási meghatalmazott |
|---|---|
EnsureCreated vagy Migrate |
UseSeeding |
EnsureCreatedAsync vagy MigrateAsync |
UseAsyncSeeding |
dotnet ef database update vagy Update-Database |
UseSeeding |
| Migrálási csomag | UseSeeding |
| Külső SQL-eszköz által végrehajtott SQL-szkript | None |
A futtatandó UseSeedingautomatizált üzembe helyezéshez használjon migrálási csomagot vagy dedikált inicializálási folyamatot. Az EF Core-eszközök és -csomagok meghívják a szinkron delegáltat, így mindig implementálhatók UseSeeding akkor is, ha az alkalmazás általában aszinkron API-kat használ. Sql-szkriptet használjon, amikor felülvizsgálatra vagy DBA-végrehajtásra van szükség, és a magadatokat inkább migrálási műveletek jelölik. Lásd : Migrálások alkalmazása a kompromisszumokra.
A vetés a migrálás visszalépése után is fut. Ha az alkalmazás támogatja az áttelepítést olyan migrálásra, amely nem tartalmazza a kezdőkód által használt összes táblát, ellenőrizze, hogy a szükséges séma létezik-e a lekérdezés előtt. Ez különösen akkor fontos, ha az összes áttelepítést célba adásával visszaállítja 0.
Az Aspire-alkalmazások koordinálhatják a helyi migrálás végrehajtását, és közzétehetnek migrálási csomagokat vagy szkripteket az Aspire EF Core migrálási integrációjával.
Egyéni inicializálási logika
Az adatekjesítés végrehajtásának egyszerű és hatékony módja, ha a SaveChangesAsync-t használja, mielőtt a fő alkalmazáslogika végrehajtása elkezdődik. Erre a célra ajánlott UseSeeding és UseAsyncSeeding használni, de néha ezek a módszerek nem jó megoldás. Példaforgatókönyv, ha a vetéshez két különböző kontextust kell használni egy tranzakcióban. Az alábbiakban egy kódminta látható, amely közvetlenül egyéni inicializálást hajt végre az alkalmazásban:
using (var context = new DataSeedingContext())
{
await context.Database.EnsureCreatedAsync();
var testBlog = await context.Blogs.FirstOrDefaultAsync(b => b.Url == "http://test.com");
if (testBlog == null)
{
context.Blogs.Add(new Blog { Url = "http://test.com" });
await context.SaveChangesAsync();
}
}
Figyelmeztetés
Az inicializáló kód nem lehet része a normál alkalmazásvégrehajtásnak, mivel ez egyidejűségi problémákat okozhat, ha több példány fut, és ehhez az alkalmazásnak jogosultsággal kell rendelkeznie az adatbázisséma módosításához.
Az üzembe helyezés korlátaitól függően az inicializálási kód többféleképpen is végrehajtható:
- Az inicializálási alkalmazás helyi futtatása
- Az inicializálási alkalmazás központi telepítése a főalkalmazással, az inicializálási rutin meghívása, az inicializálási alkalmazás letiltása vagy eltávolítása.
Ez általában közzétételi profilokhasználatával automatizálható.
Felügyelt adatok modellezése
Az adatok entitástípushoz is társíthatók a modellkonfiguráció részeként. Ezután az EF Core migrálások automatikusan kiszámítják, hogy milyen beszúrási, frissítési vagy törlési műveleteket kell alkalmazni az adatbázis új verziójára való frissítéskor.
Figyelmeztetés
A migrálások csak a modell módosításait veszi figyelembe annak meghatározásakor, hogy milyen műveletet kell végrehajtani a felügyelt adatok kívánt állapotba helyezéséhez. Így a migráláson kívül végrehajtott adatok bármilyen módosítása elveszhet, vagy hibát okozhat.
Például ez konfigurálja a felügyelet alá vont adatokat egy Country számára OnModelCreating:
modelBuilder.Entity<Country>(b =>
{
b.Property(x => x.Name).IsRequired();
b.HasData(
new Country { CountryId = 1, Name = "USA" },
new Country { CountryId = 2, Name = "Canada" },
new Country { CountryId = 3, Name = "Mexico" });
});
Kapcsolatsal rendelkező entitások hozzáadásához meg kell adni az idegenkulcs-értékeket:
modelBuilder.Entity<City>().HasData(
new City { Id = 1, Name = "Seattle", LocatedInId = 1 },
new City { Id = 2, Name = "Vancouver", LocatedInId = 2 },
new City { Id = 3, Name = "Mexico City", LocatedInId = 3 },
new City { Id = 4, Name = "Puebla", LocatedInId = 3 });
A több-a-többhöz navigációk adatainak kezelésekor az illesztési entitást explicit módon kell konfigurálni. Ha az entitástípus rendelkezik rejtett állapotú tulajdonságokkal (pl. az alábbi LanguageCountry kapcsoló entitás esetében), névtelen osztállyal lehet értékeket adni.
modelBuilder.Entity<Language>(b =>
{
b.HasData(
new Language { Id = 1, Name = "English" },
new Language { Id = 2, Name = "French" },
new Language { Id = 3, Name = "Spanish" });
b.HasMany(x => x.UsedIn)
.WithMany(x => x.OfficialLanguages)
.UsingEntity(
"LanguageCountry",
r => r.HasOne(typeof(Country)).WithMany().HasForeignKey("CountryId").HasPrincipalKey(nameof(Country.CountryId)),
l => l.HasOne(typeof(Language)).WithMany().HasForeignKey("LanguageId").HasPrincipalKey(nameof(Language.Id)),
je =>
{
je.HasKey("LanguageId", "CountryId");
je.HasData(
new { LanguageId = 1, CountryId = 2 },
new { LanguageId = 2, CountryId = 2 },
new { LanguageId = 3, CountryId = 3 });
});
});
A saját entitástípusok hasonló módon konfigurálhatók:
modelBuilder.Entity<Language>().OwnsOne(p => p.Details).HasData(
new { LanguageId = 1, Phonetic = false, Tonal = false, PhonemesCount = 44 },
new { LanguageId = 2, Phonetic = false, Tonal = false, PhonemesCount = 36 },
new { LanguageId = 3, Phonetic = true, Tonal = false, PhonemesCount = 24 });
További információért tekintse meg a teljes mintaprojekt.
Miután az adatokat hozzáadta a modellhez, a módosítások alkalmazásához migrációkat kell használni.
HasData a módosítások át lesznek alakítva InsertData, UpdateDataés DeleteData műveleteket hajtanak végre a migrálás során. A hívás Migrate nem vizsgálja meg egymástól függetlenül az aktuális HasData konfigurációt. A modell által felügyelt adatok módosítása után adjon hozzá és helyezzen üzembe egy új migrálást.
Borravaló
Az automatizált üzembe helyezéshez használjon migrálási csomagot. Sql-szkriptet akkor használjon, ha a végrehajtás előtt meg kell tekinteni vagy módosítani kell.
Alternatívaként a(z) EnsureCreatedAsync segítségével létrehozhat egy új adatbázist, amely kezelt adatokat tartalmaz, például egy tesztadatbázis számára, vagy a memóriabeli tároló, illetve bármely nem relációs adatbázis használatakor. Vegye figyelembe, hogy ha az adatbázis már létezik, EnsureCreatedAsync nem frissíti a sémát és a felügyelt adatokat az adatbázisban. Relációs adatbázisok esetén nem szabad meghívni EnsureCreatedAsync, ha migrálást tervez használni.
Jegyzet
Az adatbázis feltöltése az "adatbevetésnek" nevezett HasData módszerrel. Ez az elnevezés helytelen elvárásokat állít be, mivel a funkció számos korlátozással rendelkezik, és csak bizonyos adattípusokhoz megfelelő. Ezért döntöttünk úgy, hogy átnevezzük a "modell által felügyelt adatokra". UseSeeding és UseAsyncSeeding módszereket kell használni az általános célú adatbevetéshez.
A modell által felügyelt adatok korlátozásai
Ezt az adattípust migrálások kezelik, és az adatbázisban már meglévő adatok frissítéséhez szükséges szkriptet az adatbázishoz való csatlakozás nélkül kell létrehozni. Ez bizonyos korlátozásokat vezet be:
- Az elsődleges kulcs értékét akkor is meg kell adni, ha azt általában az adatbázis hozza létre. A rendszer a migrálások közötti adatváltozások észlelésére szolgál.
- A korábban beszúrt adatok törlődnek, ha az elsődleges kulcs bármilyen módon módosul.
Ezért ez a funkció leginkább olyan statikus adatok esetében hasznos, amelyek várhatóan nem változnak a migráláson kívül, és nem függ az adatbázisban lévő bármi mástól, például az irányítószámoktól.
Ha a forgatókönyv az alábbiak bármelyikét tartalmazza, ajánlott az első szakaszban leírt UseSeeding és UseAsyncSeeding metódusokat használni:
- Ideiglenes adatok teszteléshez
- Az adatbázis állapotától függő adatok
- Nagy méretű adatok (a bevetési adatok a migrációs pillanatképekben kerülnek rögzítésre, és a nagy adatmennyiség gyorsan hatalmas fájlokhoz és teljesítményromláshoz vezethet).
- Az adatbázis által generálandó kulcsértékeket igénylő adatok, beleértve azokat az entitásokat is, amelyek alternatív kulcsokat használnak identitásként
- Egyéni átalakítást igénylő adatok (amelyeket nem értékkonvertálásokkezelnek), például jelszókivonatok
- Külső API-ra irányuló hívásokat igénylő adatok, például ASP.NET Core Identitásszerepkörök és felhasználók létrehozása
- Nem rögzített és determinisztikusan nem meghatározott adatok, például a
DateTime.Nowiniciálása.
Manuális migrálás testreszabása
Migrálás hozzáadásakor a HasData-n megadott adatok változásai InsertData(), UpdateData()és DeleteData()hívássá alakulnak át. A HasData néhány korlátozásának megkerülésére az egyik módszer az, ha manuálisan hozzáadja ezeket a hívásokat, vagy egyéni műveleteket, a migráláshoz.
migrationBuilder.InsertData(
table: "Countries",
columns: new[] { "CountryId", "Name" },
values: new object[,]
{
{ 1, "USA" },
{ 2, "Canada" },
{ 3, "Mexico" }
});
migrationBuilder.InsertData(
table: "Languages",
columns: new[] { "Id", "Name", "Details_PhonemesCount", "Details_Phonetic", "Details_Tonal" },
values: new object[,]
{
{ 1, "English", 44, false, false },
{ 2, "French", 36, false, false },
{ 3, "Spanish", 24, true, false }
});
migrationBuilder.InsertData(
table: "Cites",
columns: new[] { "Id", "LocatedInId", "Name" },
values: new object[,]
{
{ 1, 1, "Seattle" },
{ 2, 2, "Vancouver" },
{ 3, 3, "Mexico City" },
{ 4, 3, "Puebla" }
});
migrationBuilder.InsertData(
table: "LanguageCountry",
columns: new[] { "CountryId", "LanguageId" },
values: new object[,]
{
{ 2, 1 },
{ 2, 2 },
{ 3, 3 }
});
Ezek a műveletek akkor megfelelőek, ha az értékek és kulcsok ki vannak javítva az áttelepítés írásakor. Nem kérdezik le az adatbázis aktuális állapotát. Tekintse meg a migrálási adatműveleteketInsertData, például a , UpdateData, DeleteData, és a szolgáltatóspecifikus SQL-átalakításokat.