PV178 Úvod do Entity Frameworku Mgr. David Gešvindr MVP MSP MCSD: Windows Store MCSE: Data Platform gesvindr@mail.muni.cz
Osnova 1. Úvod do Entity Frameworku 2. Návrh databáze s využitím Entity Framework Code First 3. Entity Framework Code First Migrations
Osnova 1. Úvod do Entity Frameworku 2. Návrh databáze s využitím Entity Framework Code First 3. Entity Framework Code First Migrations
Hlavní vrstvy aplikací Presentation Layer Business Layer Data Access Layer
Přístup k relační databázi Relační databáze jsou nejrozšířenější druh úložiště pro uložení dat informačních systémů Problém: Data jsou uložená v tabulkách, ale my k nim potřebujeme přistupovat jako k objektům v C#
Přístup k relační databázi Řešení: V rámci vrstvy DAL naimplementujeme přístup k DB (SqlConnection, SqlCommand), který bude poskytovat rozhraní pro práci s daty pro vyšší vrstvy Výhody: Máme kontrolu nad databázovými operacemi (DB odborník, optimalizace) Nízká režie Nevýhody: Zbytečně pracné - Nešla by tato logika pro přístup k datům vygenerovat na základě znalosti schématu databáze?
Object-relational mapping (ORM) Technika, kdy dochází ke konverzi dat mezi nekompatibilním typovým systémem relačních databází a objektově orientovaných programovacích jazyků Relační databáze je mapována na objekty Výhody: Podstatné snížení nákladů na tvorbu DAL vrstvy Nevýhody: Při práci s objekty vývojáři často zapomínají, že dochází k drahým dotazům do databáze Generované SQL dotazy nemusí být efektivní Omezení možností databáze nebo jazyka SQL
ORM frameworky v.netu Spolu s přidáním podpory pro LINQ byl do.netu přidán i první ORM framework LINQ To SQL (2007) Podpora pouze pro Microsoft SQL Server Pro každou mapovanou tabulku je vytvořena třída podle jejího schématu, která reprezentuje řádek v dané tabulce Tato třída se též často označuje jako entita Je také možné mapovat uložené procedury a databázové funkce Přístup k databázi zajišťuje třída DataContext Každá mapovaná tabulka odpovídá stejnojmenné property Implementuje Unit of Work
ORM frameworky v.netu NHibernate opensource ORM framework, který je portací frameworku Hibernate z Javy Stránka projektu: http://nhibernate.info/ NuGet balíček: https://www.nuget.org/packages/nhibernate/ Entity Framework Microsoft Uveden spolu s.net 3.5 SP1 (srpen 2008) Nástupce LINQ to SQL (není omezený pouze na Microsoft SQL Server) Verze 1.0 neuměla ani zlomek toho, co LINQ to SQL Druhá verze byla označena jako Entity Framework 4 (2010)
Entity Framework Entity Framework 6 byl uvolněn jako open-source http://entityframework.codeplex.com/ Aktuálně dostupná verze 6.1 Oddělení od jádra.netu, instaluje se přes NuGet: https://www.nuget.org/packages/entityframework Ve vývoji Entity Framework Core 1.0 Více informací: https://www.wug.cz/zaznamy/303-entity- Framework-Core-1
Volba správného přístupu Nová DB Model First Vytvoříme model v designeru Databázi vygenerujeme z modelu Třídy se vygenerují samy Code First (nová databáze) Definujeme třídy a mapování v kódu Databázi vygenerujeme z modelu Existující DB Database First Model se vygeneruje na základě existující databáze Třídy se vygenerují samy z modelu Code First (exist. databáze) Vygenerujeme kód tříd a mapování na základě existující DB
Database First přístup Tento přístup je vhodný, pokud chcete mapovat existující databázi do Entity Frameworku EF model i třídy pro práci s daty jsou vygenerovány na základě schématu databáze Postup: 1. Založíme nový EF model 2. Vybereme databázi, která bude používána 3. Vybereme objekty, které chceme mapovat 4. Model uložíme a můžeme začít používat
Model First přístup Tento přístup je vhodný, pokud nemáte databázi a místo popisu v kódu ji chcete namodelovat s pomocí EF designéru Postup: 1. Založíme nový EF Data Context 2. S pomocí designéru vytvoříme entity (tabulky) včetně jejich vazeb 3. Model necháme převést do podoby SQL skriptu pro založení databáze, který spustíme 4. Uložíme model a můžeme jej začít používat
Osnova 1. Úvod do Entity Frameworku 2. Návrh databáze s využitím Entity Framework Code First 3. Entity Framework Code First Migrations
Code First přístup Tento přístup je modernější variantou Model First přístupu, kdy nevytváříme model v designéru, ale přímo popisujeme třídy, které tvoří doménový model Databáze je vygenerována na základě vytvořených tříd: 1. Vytvoříme třídy reprezentující řádky tabulky (entity) 2. Vytvoříme třídu reprezentující vlastní DbContext, dědící z DbContext 3. Do vlastního DbContextu pro každou tabulku přidáme property DbSet<T> Generování databáze se řídí zabudovanými nebo vlastními konvencemi
DbContext Třída, jejíž hlavní zodpovědností je správa instancí entit (entita = objekt načtený z databáze) Vytvoření instancí entit při načtení dat z databáze Zajistí, že opakované načtení řádku vrátí stejnou instanci entity (Návrhový vzor Identity Map) Sledování změn provedených nad entitami Uložení změn do databáze Návrhový vzor Unit of Work Je vhodné, aby instance kontextu byla uvolněna po dokončení business transakce Zejména u desktopových aplikací by jeden kontext existující po celý čas běhu aplikace mohl způsobovat paměťové problémy
Inicializace databáze Cestu pro připojení k databázi určíte tím, jaký parametr předáte rodičovskému DbContextu: 1. Bez parametru Připojení k.\sqlexpress nebo (localdb)\mssqllocaldb Název DB: Namespace.ClassName 2. Název databáze Připojení k.\sqlexpress nebo (localdb)\mssqllocaldb Název DB: Podle parametru 3. Název klíče v app.config nebo web.config, kde je uložený connection string k databázi
Inicializace databáze 3. Název klíče v app.config nebo web.config, kde je uložený connection string k databázi
Database Initialization Strategy Určuje, kdy a jak bude vytvořena databáze: CreateDatabaseIfNotExists Výchozí nastavení DropCreateDatabaseIfModelChanges DropCreateDatabaseAlways Custom DB Initializer Vlastní inicializace databáze Dědíme a rozšiřujeme existující inicializační strategii Výhodné třeba pro doplnění inicializace dat (Seed Data)
Inicializace dat v databázi Code First podporuje v rámci vlastního iniciátoru databáze přepsat metodu Seed
Zabudované konvence Primary Key Convention Entity Fremework vyžaduje, aby tabulka měla primární klíč Pokud se property entity jmenuje {ClassName}Id a je číselného typu nebo Guid, automaticky se stane primárním klíčem Relationship Convention Pokud v jedné entitě uvedeme jako typ property jinou třídu, automaticky se vytvoří navigation property a cizí klíč Je vhodné vazbu uvádět oboustranně Pro vazbu 1:N vytvoříme property typu ICollection<T> Pro vazbu M:N budou v obou entitách property typu kolekce
Zabudované konvence Foreign key Convention Pokud vytvoříme property stejného jména a typu jako je klíč v tabulce na kterou se odkazujeme, automaticky se tato property použije jako cizí klíč Type Discovery Pokud v entitě uvedete jako property další třídu, pro kterou neexistuje DbSet<T> v rámci kontextu, sám se vytvoří
Data Annotations Data Annotations lze použít k popisu metadat o vytvářených tabulkách Používají se, pokud nevyhovují zabudované konvence Podporované anotace: [Key] [Required] [MaxLength(50)], [StringLength(50)], [MinLength(2)] [Index], [Index(IsUnique = true)] [Table("Products")] [Column("Name")] [ForeignKey("StandardRefId")] [NotMapped] [TimeStamp] [ConcurrencyCheck]
Osnova 1. Úvod do Entity Frameworku 2. Návrh databáze s využitím Entity Framework Code First 3. Entity Framework Code First Migrations
Code First Migrations Technologie, která umožňuje aktualizovat databázi na novou verzi bez ztráty dat Volíme si, jestli databázi aktualizovat ručně nebo automaticky V projektu se vytvářejí snapshoty verzí datového modelu, které vždy popisují migraci na vyšší ale i zpět na nižší verzi Popis migrace lze rozšířit o vlastní logiku, pro vhodnou migraci dat
Jak používat Code First Migrations 1. Do konzole Tools Library Package Manager Package Manager Console zadejte příkaz enable-migrations 2. Dojde k povolení migrací a vytvoření iniciálního stavu databáze/modelu 3. Po provedení změn v modelu se ve stejné konzoli volá příkaz add-migration Název migrace 4. Pro ruční aktualizaci databáze se volá příkaz update-database Výchozí chování je aktualizace na poslední verzi DB Je možné specifikovat i cílovou verzi pomocí jejího názvu
Automatická migrace databáze Code First Migrations poskytují nový databázový initializer: public EshopContext() : base() { Database.SetInitializer( new MigrateDatabaseToLatestVersion<EshopContext,Migrations.Configuration>()); } Po jeho aplikaci bude docházet k automatické aktualizaci databáze na nejnovější verzi