Korábban megnéztük, hogy mi a helyzet, ha zöldmezős adatbázist készítünk. Ebben az esetben a code first megoldás jól működik. De mi a helyzet akkor, ha már létezik egy adatbázis sémánk és ahhoz szeretnénk egy Entity Framework modellt illeszteni?
Ebben az esetben két lehetőségünk van. Manuálisan lekódoljuk a modellt a code first esetén tanultakkal, vagy az Entity Framework parancssori eszközével létrehozzuk a modellt. Az Entity Framework dokumentációja ezt a folyamatot Reverse engineeringnek, régi nevén scaffolding-nak nevezi.
Ahhoz, hogy egy meglévő adatbázis alapján modellt generáljunk, a cél projektünknek tartalmaznia kell a korábban említett három NuGet csomagot.
Ezt követően a következő parancsot kell kiadnunk:
dotnet ef dbcontext scaffold "Data Source=teszt.sqlite" Microsoft.EntityFrameworkCore.Sqlite
Az első paraméter az adatbázis kapcsolatot határozza meg, a második paraméter pedig az adatbázishoz használandó DB támogató csomag neve.
A parancs kiadása után az adatbázisban található összes táblája entitástípusokra lesz visszafejtve. A --table kapcsolóval korlátozható, hogy melyik táblákat szeretnénk generáltatni. Például ha csak a Publisher és Author táblákat, akkor ezt a parancsot kell kiadni:
dotnet ef dbcontext scaffold "Data Source=teszt.sqlite" Microsoft.EntityFrameworkCore.Sqlite --table Author --table Publisher
Mivel a tábla és oszlop nevek egy meglévő DB esetén nem feltétlen illeszkednek a .NET Pascal Casing sémájába, ezért a scaffold parancs automatikusan átnevezi a generált kódban az osztályokat és tulajdonságokat, hogy illeszkedjenek a .NET nevezéktanba. Azonban a --use-database-names kapcsoló letiltja ezt a viselkedést, és amennyire csak lehetséges, megőrzi az eredeti adatbázisneveket. Az érvénytelen .NET-azonosítók továbbra is ki lesznek javítva, és a szintetizált nevek, például a navigációs tulajdonságok továbbra is megfelelnek a .NET elnevezési konvencióknak.
Az entitásokat a Fluent API használatával konfigurálja az eszköz. A --data-annotations kapcsoló megadása arra utasítja a generálást, hogy attribútumokkal konfiguráljon, amikor ez lehetséges.
A létrehozott DbContext osztálynév az adatbázis neve lesz alapértelmezés szerint Context utótaggal. Ha más nevet szeretnénk használni, akkor a --contextet opció után megadott névvel ezt felülbírálhatjuk.
Limitációk
- A modellekkel kapcsolatban nem minden ábrázolható adatbázisséma segítségével. Például az öröklődési hierarchiákra, a tulajdonolt típusokra és a táblafelosztásra vonatkozó információk nem jelennek meg az adatbázissémában. Emiatt ezek a konstrukciók soha nem lesznek visszafejtve.
- Előfordulhat, hogy egyes oszloptípusokat az EF Core szolgáltató nem támogat. Ezek az oszlopok nem fognak szerepelni a modellben.
- Egy EF Core modellben concurrency tokeneket határozhat meg, hogy megakadályozza, hogy két felhasználó egyszerre frissítse ugyanazt az entitást. Egyes adatbázisok rendelkeznek egy speciális típussal az ilyen típusú oszlopok megjelenítésére (például rowversion az MS SQL Serverben), ebben az esetben visszafejtésre kerül ez az információ, azonban más concurrency tokenek nem lesznek visszafejtve.