Miroslav Holec
Premium

Entity Framework Core 5 a porovnání s tradičním EF 6

Miroslav Holec   21. května 2021

Tento článek je již zastaralý. Článek nemusí popisovat aktuální stav technologie, ideální řešení a můj současný pohled na dané téma.

Modernizovaný framework EF Core se dočkal koncem roku 2020 své páté verze. Mnoho vývojářských týmů na svých projektech stále používá EF 6 a teprve nyní zvažuje přechod na nový EF Core. Mezi nejčastější důvody používání EF 6 patřila buď nedospělost nového EF Core nebo používání staršího stacku s .NET Frameworkem, kde přechod neměl smysl. V článku si oba ORM porovnáme a vysvětlíme si klíčové rozdíly.

Základní ideologie

Aktuální verzi EF Core 5 může vývojář zapojit do všech running frameworků a knihoven s podporou .NET Standard 2.1. Nelze jej tedy používat v tradičním .NET Frameworku. EF Core umožňuje modelování metodou Code First. V praxi tedy vývojář píše kód, ze kterého se vytváří tzv. migrace. Ty obsahují instrukce pro update nebo downgrade cílového úložiště. Migrace je oproti EF 6 nutné vždy vytvářet ručně a i nadále je možné do nich ručně dle potřeby dopsat vlastní SQL. Stejně jako v EF6 se může vývojář rozhodnout, zda vytvořené migrace aplikuje proti úložišti skrze vygenerované scripty nebo použije automatické provedení migrací. V EF Core se nepoužívají vizuální modely a přístupy Database First či Model First. Tyto přístupy není v plánu implementovat. Nakonec je možné si existující úložiště tzv. scaffoldovat do modelu (podoby kódu) a nadále se o tento model starat ručně. Je tedy možné spravovat ručně například SQL databázi a podle změn si ručně měnit i kód v aplikaci. Vygenerovaný model nelze na základě změn v databázi aktualizovat.

DbContext a Dependency Injection

Stejně jako v EF 6 i nadále vývojář pracuje s tzv. DbContextem. Ten lze nyní snadno registrovat do výchozího MS DI kontejneru. V současné době lze registrovat DbContext přímo nebo skrze tzv. DbContextFactory, která je pak schopná v dočasném scope DbContext poskytnout. Využití najde například v případě Blazor nebo desktopových aplikací. Při zapojení SqlServer providera jsou nově k dispozici rozšiřující nastavení pro Azure databáze. Dále je možné nastavit například retency policies v případě, že se nedaří k úložišti připojit. Konfigurace skrze DI též provádí provázání s logging factory a lze tudíž během debugování procházet logy s generovanými SQL dotazy. Nad rozhraním IQueryable je dále možné vygenerovat SQL dotaz pro účely debuggingu.

Providers

EF Core má aktuálně podporu ve všech nejrozšířenějších datových úložištích. Nejlepší podpoře se těší zejména SqlServer a Sqlite. Dále Microsoft přidal podporu tzv. In-Memory databáze, která může posloužit pro základní experimentování a nebo psaní jednodušších unit testů. V posledních verzích dále MS přidal podporu pro Azure Cosmos DB, čili je možné pracovat i se strukturovanými daty. Další providers jsou dodávány externě. Krátce po releasu nových verzí EF Core se lze dočkat aktualizace providerů pro PostgreSQL a díky Jirkovi Činčurovi též Firebirdu. Další providers mají většinou znatelné zpoždění s distribucí nových verzí.

Dotazování

Nadále je možné vytvářet dotazy, které lze rozdělit na trackovatelné a netrackovatelné. Netrackovatelné jsou zpravidla rychlejší a vhodné pro read operace. Toto nastavení je nyní možné nastavit globálně dle preferencí a poté jej u každého dotazu dle potřeby též přetížit. Vývojář se dále může rozhodnout, zda si nechá vrátit data skrze jeden dotaz, nebo zda si nechá vygenerovat za cenu nekonzistence více dotazů (tzv. split query). I toto chování lze nastavit globálně a na úrovni dotazů měnit. Nakonec se hodí zmínit, že v EF Core byla odstraněna výchozí podpora pro Lazy Loading. Ten je nyní možné zapojit skrze separátní NuGet balíček. V souvislosti s tím je možné použít konstruktor entit pro předání dalších závislostí a práci s Lazy Loadingem.

K dotazování lze dodat, že jednodušší generované dotazy jsou obvykle srozumitelnější než u EF 6. U složitějších dotazů už je to občas horší. Zejména v kombinaci s groupováním EF Core přinutí vývojáře občas sáhnout po tradičním SQL nebo ustoupit na úkor výkonnosti a nechat si provést výpočty in-memory.

Anotace a Fluent API

I v moderním EF Core lze popsat model a vztahy mezi entitami pomocí tzv. anotací (datových atributů) nebo skrze fluent API (samostatné konfigurační pravidla). Stále platí, že nejvyšší prioritu má fluent API a skrze něj lze provádět všechna nastavení. Pomocí anotací lze popsat pouze základní nastavení.

Mnoho nových API

Naprostá většina funkcionalit byla přenesena z EF 6 a zároveň Microsoft přidal velké množství drobných vylepšení, která v EF 6 nikdy nebyla. Kromě properties lze i pro jednotlivé modely nastavit ignoraci a vyloučení z migrací. Lze tak separátně udržovat více modelů a v nich vybrané entity. V rámci dotazování je možné pracovat s entitami bez primárních klíčů. Lze snadno provést mapování na DB views nebo funkce. Pomocí query filtrů lze dále pracovat s kolekcemi, které jsou již předfiltrované dle zvolených pravidel. Tato pravidla lze přitom na úrovni jednotlivých dotazů dle potřeby ignorovat. Rozšířené funkcionality se dočkaly tzv. komplexní typy (nově owned types) a dále je možné používat value conversions pro snadnou konverzi mezi datovými typy. Kromě celé řady předdefinovaných konverzí si lze vytvářet též vlastní pravidla mapování.

Výborná podpora pro DDD

EF Core nabízí plno malých a užitečných funkcí pro vytváření DDD aplikací. Lze tak například namapovat SQL databázi na entity splňující nároky na zapouzdření. V první řadě lze promapovat private fields a properties, dále je možné snadno vytvářet values types pomocí owned types a v neposlední řadě je velmi snadné a intuitivní popisovat vztahy mezi aggregate roots „z jedné strany“. Pro vývojáře používající domain driven design je tak nově snadné pomocí jednoho ORM sestavit kompletní bounded context bez potřeby vytvářet další mapování mezi aggregate roots a primitivními ORMkovými POCO třídami.

Pár chybějících funkcionalit

Oproti EF 6 můžete v EF Core některé funkce též postrádat. Kromě vizuálního modelování chybí podpora pro update modelu z databáze. Dále není podporována TPC dědičnost, špatně se pracuje s uloženými procedurami a některé dotazy založené na nových funkcích stále EF Core neumí přeložit na SQL. Naštěstí již v listopadové LTS verzi se dočkáme podpory mnoha dalších funkcí. Přibyde možnost práce s temporal tables, sloupci obsahujícími JSON data a budou s trochou štěstí napraveny zmíněné nedostatky u pokročilých dotazů. Podle všeho bychom se mohli dočkat i nového bulk API, vylepšené podpory mapování views a konečně i uložených procedur. Kompletní přehled plánů najdete na GitHubu.

Nástroje pro správu

Nástroje pro správu se zásadně nemění v případě, že používáte Package Manager konzoli. Nově je možné používat nástroj dotnet ef, který se těší podpoře i na platformě Linux a macOS. Model tak lze obsluhovat kompletně z příkazové řádky a bez nutnosti používat Visual Studio.

Závěrem

Přestože má EF Core drobné mouchy k vyladění, funkčně se již dostal na úroveň EF 6 a v současné době nabízí již celou řadu nových funkcí, které EF 6 neumí a nikdy umět nebude. Určitou jistotu dodává stále možnost dopsat si SQL dotazy dle potřeby ručně nebo využít například mapování na Views. Jako velkou výhodu nakonec vnímám práci s ORM v případě domain driven aplikací nebo s Cosmos Db. Určitý potenciál též může mít prvotní investigace vývojářů do podpory GraphQL. Trváte-li naopak na vizuálním modelování, píšete velmi složité SQL dotazy nebo používáte exotické providers, ORM vás pravděpodobně příliš neuspokojí.

Webinář a školení EF Core 5

Chcete-li se podívat na modelování v nové verzi EF Core 5 a ověřit si, zda je pro Vás tento ORM vhodný, přihlaste se na můj červnový webinář. Chcete-li s EF Core začít pracovat a nevíte kudy kam, mrkněte i na mé celodenní školení EF Core.