Při práci s databázemi v .NET je Entity Framework Core (EF Core) jedním z nejpopulárnějších nástrojů pro správu a manipulaci s daty. Tento nástroj umožňuje využívat objektově-relační mapování (ORM), které propojuje databázové tabulky s objekty ve vaší aplikaci. Při generování modelů z existujících databází můžeme pomocí příkazu dbcontext scaffold automaticky vygenerovat potřebné třídy. Tento proces je velmi užitečný, protože nám šetří čas při práci s databázemi a zároveň umožňuje udržet kód efektivní a konzistentní. Pojďme se podívat na jednotlivé kroky, jak tento proces funguje a co všechno bychom měli vzít v úvahu při generování a úpravách modelů.
Příkaz dbcontext scaffold slouží k vygenerování tříd na základě existující databáze. Při jeho použití je potřeba správně nastavit parametry, jako je například řetězec pro připojení k databázi, poskytovatel databáze, výstupní složka, namespace nebo použití datových anotací. Příkaz vypadá takto:
Tento příkaz provádí několik důležitých akcí. V první řadě, je specifikováno, že používáme poskytovatele Microsoft.EntityFrameworkCore.SqlServer, což znamená, že připojujeme databázi SQL Server. Dále je určeno, že modely budou generovány do složky Models a že budou použity datové anotace místo Fluent API pro konfiguraci entit.
Pokud pracujeme s databází Azure SQL nebo Azure SQL Edge, musíme upravit řetězec pro připojení tak, aby odpovídal specifickému prostředí. To je důležité pro zajištění správné komunikace mezi aplikací a databází na těchto platformách.
Po dokončení scaffoldingu se vytvoří více než 25 tříd, které odpovídají tabulkám v databázi. Jednou z těchto tříd je například Category.cs, která reprezentuje řádek v tabulce Categories. U této třídy je důležité si všimnout několika klíčových vlastností, které jsou použity pro konfiguraci entit:
-
Atribut
[Index]: Tento atribut, který byl zaveden v EF Core 5.0, označuje vlastnosti, které by měly být indexovány. To je užitečné pro optimalizaci dotazů, zejména v případě, že s těmito vlastnostmi často pracujeme. -
Atribut
[Key]: Tento atribut určuje primární klíč entity, což v tomto případě odpovídá vlastnostiCategoryId. -
Atribut
[InverseProperty]: Tento atribut slouží k definování cizího klíče, který odkazuje na jinou entitu. V tomto případě je definován vztah mezi kategorií a produkty pomocí cizího klíče.
Pokud se podíváme na třídu ProductsAboveAveragePrice.cs, všimneme si, že reprezentuje řádek vrácený databázovým pohledem (view), nikoli tabulkou. Proto je tato třída označena atributem [Keyless], což znamená, že nemá primární klíč.
Důležitou součástí generovaných tříd je také DbContext třída, která je zodpovědná za správu entit a jejich propojení s databází. Třída NorthwindDb.cs je příkladem takové třídy. Tato třída obsahuje několik klíčových částí:
-
Konstruktory: Třída má dva konstruktory. Jeden bez parametrů a druhý, který umožňuje předat konfigurační možnosti, jako je například připojovací řetězec.
-
DbSet vlastnosti: Každá vlastnost typu
DbSet<T>představuje tabulku v databázi. Tato vlastnost je automaticky generována pro každou tabulku v databázi a umožňuje snadnou manipulaci s daty. -
Metoda
OnConfiguring: Tato metoda se používá pro konfiguraci připojení k databázi. Pokud není připojení specifikováno, používá se výchozí řetězec připojení.
U generovaných modelů je také důležité poznamenat, že jsou použity datové anotace i Fluent API pro konfiguraci entit. To znamená, že některé aspekty modelů jsou definovány pomocí atributů přímo v třídách (např. [Key], [StringLength]), zatímco složitější konfigurace, jako jsou vztahy mezi entitami, jsou definovány pomocí Fluent API ve třídě OnModelCreating.
Pokud chcete mít plnou kontrolu nad konfigurací, můžete upravit metody OnModelCreating a OnConfiguring. Například v metodě OnModelCreating můžete přidávat nové vztahy mezi entitami nebo měnit chování existujících entit bez toho, abyste museli znovu generovat třídy.
Další důležitou součástí je správné nakládání s připojovacím řetězcem. Případné citlivé informace by měly být uloženy mimo zdrojový kód, ideálně v konfiguraci aplikace. Efektivní způsob správy připojovacích řetězců je použití konfiguračních souborů, což také zvyšuje bezpečnost aplikace.
Pokud se rozhodnete pro generování modelů z existující databáze, je důležité si být vědom několika věcí. Třídy, které jsou generovány, jsou pouze základními strukturami. Je nutné je upravit a přizpůsobit konkrétním potřebám vaší aplikace, například přidáním vlastních metod, validací nebo jinými úpravami, které zlepší funkčnost aplikace. Scaffoldování může také občas vést k neoptimálním názvům nebo nastavením, které je potřeba přehodnotit.
V závěru je třeba zmínit, že i když nástroje jako EF Core scaffold usnadňují práci s databázemi, vždy je potřeba rozumět tomu, jak tento nástroj funguje a jaké má limity. Při používání scaffoldingu je dobré mít na paměti možnost úpravy generovaných tříd podle potřeby, což může zahrnovat přidání vlastních konfigurací nebo změny ve struktuře modelů.
Jak správně mapovat dědičnost v relačních databázích pomocí SQL Serveru
Při modelování dědičnosti v relačních databázích je jedním z hlavních rozhodnutí výběr strategie mapování, která bude použita k implementaci hierarchie tříd. Ve světě SQL Serveru existují tři hlavní přístupy, jak tuto dědičnost řešit: TPH (Table-per-Hierarchy), TPT (Table-per-Type) a TPC (Table-per-Concrete-Type). Každá z těchto strategií má své výhody a nevýhody a je důležité vybrat správnou metodu v závislosti na konkrétních požadavcích aplikace a databázové architektury.
Table-per-Concrete-Type (TPC)
U této metody je pro každý konkrétní typ vytvořena samostatná tabulka. V případě hierarchie Person-Student-Employee, TPC použije samostatnou tabulku pro každý typ, jak je to uvedeno v následujícím příkladu kódu:
V tomto příkladu je pro každý typ Student a Employee vytvořena samostatná tabulka, přičemž pro každý záznam je přiřazen unikátní identifikátor. Pro zajištění, že se ID hodnoty mezi tabulkami nebudou překrývat, používáme sekvenci:
Výhody a nevýhody TPC
Hlavní výhodou této strategie je výkon. Když dotazujeme pouze jeden konkrétní typ, potřebujeme pouze jednu tabulku, což eliminuje nákladné spojování (joins). Tato metoda se ukazuje jako efektivní pro rozsáhlé hierarchie s mnoha konkrétními typy, kde každý typ má specifické vlastnosti.
Na druhou stranu hlavní nevýhodou je, že data jsou rozptýlena po více tabulkách, což může vést k obtížnému opětovnému sestavení dat. Tato metoda tedy není vždy ideální, zejména pokud by bylo třeba provádět složité dotazy mezi více tabulkami.
Jak nakonfigurovat mapování hierarchie
Při nastavení mapování dědičnosti v Entity Frameworku je nejprve nutné definovat všechny typy, jak je to uvedeno v následujícím příkladu:
Pro použití výchozího mapování TPH není třeba provádět žádné speciální nastavení, protože je to implicitní metoda. Pokud chcete použít jiné metody, jako je TPT nebo TPC, můžete zavolat příslušnou metodu:
Kromě toho můžete specifikovat název tabulky pro každou entitu:
Pro TPC strategii je potřeba nastavit také sdílenou sekvenci, aby byly hodnoty ID konzistentní napříč tabulkami:
Praktická ukázka
Nyní si ukažme praktické použití této konfigurace. Začněte vytvořením aplikace Console App v rámci projektu, jak je uvedeno v následujících krocích:
-
Vytvořte nový projekt Console App a přidejte potřebné balíčky pro EF Core.
-
Vytvořte třídy
Person,StudentaEmployee, kde každá z nich bude odvozena od základní třídyPerson. -
Nakonfigurujte
DbContexta v metoděOnModelCreatingpoužijte správné mapovací strategie.
Příklad třídy Person:
Třídy Student a Employee dědí z Person a přidávají specifické vlastnosti:
Poté vytvořte třídu HierarchyDb, která bude obsahovat DbSet pro všechny typy:
Význam správné volby strategie
Je zásadní pochopit, že správná volba strategie mapování má přímý dopad na výkon a údržbu databáze. Použití TPC, i když zajišťuje dobrý výkon při dotazování konkrétních typů, může být nevhodné, pokud databáze obsahuje mnoho typů a komplexní dotazy mezi nimi. Naopak TPH, i když využívá jednu tabulku pro všechny typy, může vést k problémům s výkonem při složitých dotazech s velkými datovými sadami.
Při volbě mezi těmito strategiemi je tedy důležité zvážit nejen výkon, ale i údržbu databáze v dlouhodobém horizontu. Pokud je možné, vždy je dobré preferovat TPH, protože je efektivní a jednoduché na implementaci. TPC by mělo být použito v případech, kdy máte jasně oddělené konkrétní typy, každý s vlastními specifickými vlastnostmi, a kdy je výkon klíčový.
Jak světlo reaguje při průchodu různými médii?
Co se skrývá za tichým šílenstvím? Psychologická a emocionální stránka lidského utrpení
Jaký je anatomický význam laterální plochy mozku a jak ji správně rozpoznat a dissectovat?
Jak se mění svět kolem nás, když se na něj díváme zvenčí?

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский