Török János Zsolt torokjzsolt@gmail.com Entity Framework Török János Zsolt torokjzsolt@gmail.com
Agenda Élet az EF előtt Entity Framework bemutatása Az Entity Data Model Programozási koncepciók További mappelési lehetőségek Hogyan tovább
objektumok != relációs adatok Az alapprobléma Az üzleti alkalmazások nagy része relációs adatbázisban tárolja az adatokat Legalább két különböző nyelv (C# and SQL) Különböző szintaxis Különböző típusok Különböző eszközök Különböző paradigmák: objektum orientált vs. procedurális Valamint meg kell tanulni az API-t ami összeköti az adatot a kóddal: ADO.NET És a legnagyobb probléma: objektumok != relációs adatok
Ahogy EF előtt csináltuk - DataReader using (SQLConnection conn = new SQLConnection(“<conn string>”); { conn.Open(); SQLCommand cmd = conn.CreateCommand(); cmd.CommandText = “sp_StoredProc”; cmd.parameters.AddWithValue(“@City”, “Dallas”); using (SQLDataReader rdr = cmd.ExecuteReader()) while (rdr.read()) string name = rdr.GetString(0); string city = rdr.GetString(1); } Bármire képesek vagyunk, csak épp egyre több idő alatt és törékeny kódot létrehozva Hard kódolt sztringek! Nincs fordítási idejű ellenőrzés, sem Intellisense A paraméterek lazán kötve: A nevük, típusuk, darabszámuk nincs ellenőrizve futásig Az eredmények sem típusosak
Egy fokkal közelebb - DataSet dsNorthwind dsNorth = new dsNorthwind(); ProductsTableAdapter taProducts = new ProductsTableAdapter(); taProducts.Fill(dsNorth.Products); foreach (dsNorthwind.ProductsRow row in dsNorth.Products) { Response.Write(row.ProductName + " " + row.UnitPrice + "<br/>"); } A háttérben még mindig SQL szkripteket írunk és az eredmények továbbra sem az üzleti objektumainkba érkeznek
Agenda Élet az EF előtt Entity Framework bemutatása Az Entity Data Model Programozási koncepciók További mappelési lehetőségek Hogyan tovább
Mi az Entity Framework? Az Entity Framework egy olyan adatelérési keretrendszer (angolul ORM (Object-Relational Mapper) API), amely segít áthidalni a különbségeket az alkalmazás adatstruktúrája és üzleti objektumai között. Automatikusan létrehozza az adatokat reprezentáló entitásokat és a köztük lévő kapcsolatokat Olyan flexibilis objektum modellt biztosít, amely lehetővé teszi az adatok objektumokhoz kötését többféle módon is A LINQ kéréseket SQL lekérdezéssé transzformálja
Történelem 1.0 (valójában 3.5) - 2008 4.0 - 2010 4.1 – NuGet POCO, lazy loading, Model First továbbfejlesztett SQL, LINQ, designer, stb. 4.1 – NuGet DBContext és Code First appoach 6.0 – 2013 Async Query and Save, Connection Resiliency SQL logging, testability improvements, stb. Jelenleg 6.1.2, 7.0 – 2015 nyarán New platforms and data sources Lightweight and extensible
Mit csinál pontosan? Az adatok konceptuális nézetén lehet végezni az adatok elérését, nem pedig magán az adatforráson Automatikusan típusos entitás objektumok kerülnek létrehozásra, amelyek az adatok 1-1 összerendelése, de testre szabható Automatikusan létrejönnek az objektumok között a kapcsolatok Automatikusan lefordítja a LINQ lekérdezéseket SQL lekérdezésekké Automatikusan nyilván tartja a változásokat, intézi az adatbázis update/insert/delete-eket Vizuális modellező eszközt biztosít Rob Vettor
LINQ oldalról nézve LINQ Providers Query Operators C# 3.0 VB 9.0 LINQ to Objects LINQ to Datasets LINQ to SQL LINQ to Entities LINQ to XML Relational <book> <title/> <author/> <year/> <price/> </book> XML Objects
ADO.NET oldalról nézve Entity Framework Programming Model Conceptual Data Model Entity Framework LINQ to Entities, Entity SQL Programming Model ADO.NET Entity Provider (entity client) Mapping Today, with ADO.NET 2.0, We have providers that provide connections, commands, etc that are specific to a particular data store In Version 3.0, developer can build conceptual model of the store Program against model that ties closely to domain Mapping technology translates conceptual model to real store You are abstracted from underlying store and program against conceptual model instead of logical model LINQ to Entities is object-relational mapping API mapping between conceptual model and .NET types in memory, which give you the ability to use language integrated queries to manipulate the conceptual model So. in nutshell, on top you have LINQ, with Object Relational Mapping API on top of a conceptual model, which itself is mapped to is mapped to the underlying store. Store ADO.NET Data Provider (SqlClient, OracleClient) Command Connection Reader Adapter Legacy ADO.NET 2.0 does not go away! Rob Vettor
Az EF architektúrája Object Services Entity Client EDM
Agenda Élet az EF előtt Entity Framework bemutatása Az Entity Data Model Programozási koncepciók További mappelési lehetőségek Hogyan tovább
{ } Az Entity Data Model CSDL Koncepcionális modell { } MSL Megfeleltetési leírás (map) SSDL Adatbázis fizikai modell Adatbázis Objektum Tábla megfeleltetése entitás objektumnak Constraintek (elsődleges kulcs, nullozhatóság stb.) Öröklődések, sok-sok kapcsolatok kezelése
Ahogy tehát a mappelés működik SQL C# kód Adatbázis [Database] DbContext Tábla [Table] Entitás osztály Oszlopok [Column] Mezők, tulajdonságok
Entity Data Model demó EDM design módok Designer túra… Database first Model First (4.0 óta) Code First (4.1 óta) Data annotations / Fluent API Designer túra… Új Entity Data Model létrehozása a mapping wizard segítségével Entitások, skalár és navigációs tulajdonságok az EDM Designer-ben Model Browser Mapping Details EDMX file Generált entity class-ok Rob Vettor
Entity Data Model ismétlés Many-to-Many Navigation property-k reprezenálják. Elrejti az asszociációs entitást. Relationship Olyan objektum, amely az entitások közti asszociációt határozza meg Scalar Property Az entitás egy tulajdonsága Navigation Property Mutató a kapcsolódó entitás(ok)ra. Entity Az alap objektum
Agenda Élet az EF előtt Entity Framework bemutatása Az Entity Data Model Programozási koncepciók További mappelési lehetőségek Hogyan tovább
A DbContext A modell tárolója Belépési pont az entitásokhoz using (NorthwindEntities db = new NorthwindEntities()) A modell tárolója Belépési pont az entitásokhoz Adatforrás kapcsolat menedzselője Felelős az SQL generálásért A példányosított entitások lokális cache-eként szolgál Teljes változás követést biztosít Konkurencia- és tranzakció menedzsment DbContext Entity Designer Target Entity Factory DP az entitások pélányosítására
Konceptuális modell programozása Entity Client Object Services Konceptuális model lekérdezése LINQ segítségével Compile time típus ellenőrzés, debug támogatás és Intellisense A lekérdezés eredmények erősen típusos entitás objektumokba példányosulnak Erőforrás igényes: 1. Kifejezésfa elkészítése 2. Konvertálás SQL lekérdezéssé 3. Lekérdezés futtatása 4. Adatok fogadása 5. Adatok konvertálása objektumokká Új SQL dialektus eSQL Belülről ADO.NET, connection-t és command-ot generál, data reader-t ad vissza High performance – adatokat ad vissza, nem objektumokat Megkérdőjelezhető felhasználás – talán ha csak adat kell, nem pedig entitás objektumok
Query (Expression Pattern) szintaxis ismétlés from-mal kezdődik További from, join, let, where, vagy orderby A Query Expression Pattern metódusai Where Select, SelectMany OrderBy, OrderByDescending, ThenBy, ThenByDescending GroupBy Join, GroupJoin Cast<T> from id in source { from id in source | join id in source on expr equals expr [ into id ] | let id = expr | where condition | orderby ordering, ordering, … } select expr | group expr by key [ into id query ] Végül select group by Opcionálisan into-val folytatható
Metódus szintaxis ismétlés var q = from m in list where m.Title.StartsWith( "S" ) select new { m.Title, m.Length }; Query Expression Implicit típusú lokális változó Lambda kifejezések var q = list .Where( m => m.Title.StartsWith( "S" ) ) .Select( m => new { m.Title, m.Length } ); Bővítő metódusok Névtelen típus Objektum inicializáló
LINQ-To-Entities demó Szakok lekérdezése Eredmények renderelése DataGrid-be Generált SQL megtekintése SQL Profiler-el “Query szintaxis” vs. “Method szintaxis”
Generált SQL példa
Navigation Property-k Orders OrderID <pk> Order maps reference to collection of OrderDetails objects (EntitySet Type) Order-ből: navigation property használata a kapcsolódó OrderDetail entitások eléréséhez: from o in Orders where 20 < o.OrderDetails.UnitPrice select o; OrderDetails-ből: navigation property használata a szülő Order entitás eléréséhez: from d in OrderDetails where d.Order.OrderID == 1 select d; DEMÓ OrderDetails OrderDetaillD<pk> OrderID <fk> OrderDetails maps reference to single Order object (EntityRef Type)
Lekérdezések vs. tárolt eljárások EF támogatja mindkét megoldást Paraméteres lekérdezések EF automatikusan generálja SQL-ben tábla szintű jogosultságot igényelnek Tárolt eljárások Security SQL kézben tartása teljesítmény Viszont valós veszély, hogy az üzleti logika átkerül SQL oldalra…
Lazy Loading (késleltetett betöltés) A LINQ alapból a “deferred execution”-t használja Legtöbbször a lekérdezés definiáláskor nem fut le ténylegesen // define query var query = from c in ctx.Customers where c.Region == "OR" orderby c.CompanyNameselect c; // execute query dgvQuery.DataSource = query; A lekérdezés csak akkor fut le, amikor az eredményre szükség van: Kontrollhoz kötéskor Foreach ciklusban az adatokon végigiteráláskor Kollekcióvá alakításkor, pl. ToList(), ToArray() Egy objektum lekérdezésekor (aggregáláskor, vagy pl. First(), Last())
Objektum gráfok betöltése Objektum gráf: egymáshoz kapcsolódó objektumok halmaza Alapértelmezetten a gyerek objektumhalmazok egyesével töltődnek be (külön karika az adatbázis felé), amikor szükség van rájuk Az Include() metódus segítségével előre definiálhatjuk az objektum gráfot, így egyetlen lekérdezéssel töltődik be az egész a memóriába DEMÓ Customer Order Order Detail Product Category
Változás követés Az ObjectContext automatikusan követi a változásokat az ObjectStateManager objektuma segítségével Lekérdezéskor becache-eli az eredeti értékeket Mentéskor (SaveChanges()) automatikusan létrehozza az update/insert/delete SQL parancsokat Változás követés kikapcsolása (csak olvasás esetén): context.Products.MergeOption = MergeOption.NoTracking;
Update / Insert / Delete Update: entitás tulajdonságának változtatása, majd SaveChanges() Insert: több lépéses folyamat Új entitás objektum definiálása Az entitás hozzáadása az ObjectContext-hez SaveChanges() meghívása a context-en az adatbázisba mentéshez Delete: db.Products.DeleteObject(product); db.SaveChanges(); DEMÓ Változtatás, mentés ObjectStateManager megtekintése A generált SQL parancsok
Agenda Élet az EF előtt Entity Framework bemutatása Az Entity Data Model Programozási koncepciók További mappelési lehetőségek Hogyan tovább
Objektumorientált sajátosságok leképezése Öröklődés példák Table per Hierarchy Egyetlen tábla Table per Type Öröklődésenként egy tábla Splitting Több tábla egy entitásba Egy tábla több entitásba Sok-sok kapcsolat Két oszlopos kapcsolótábla DEMÓ ProductBase TestProduct Product DiscontinuedProduct Employee Territory *
Table-Per-Hierarchy összerendelés Entitások közti öröklődés – adatbázisban egy tábla Az összerendelés a discriminator column alapján történik valamilyen feltétel mentén A származtatott típusok lekérdezhetőek where feltétel nélkül az OfType() metódussal: from c in db.Products.OfType<DiscontinuedProduct>() Limitáció: nehéz a diszkriminátor oszlopot módosítani EF-el – adatbázis megoldás segít (trigger / sp) Base Type Discriminator Column Database Table Entities Product DiscontinuedFlag Product DiscontinuedProduct Derived Type
Table-Per-Type összerendelés A modellben lényegében az asszociációt cseréljük öröklődésre Kiküszöböli a navigációs tulajdonságok használatának szükségességét a bejárásra A származtatott típusok szintén hozzáférhetőek az OfType() metódus használatával Limitáció: gyermeket nem lehet törölni anélkül, hogy a szülőt is törölnénk
Feldarabolás (Splitting) Entity Splitting Table Splitting
Agenda Élet az EF előtt Entity Framework bemutatása Az Entity Data Model Programozási koncepciók További mappelési lehetőségek Hogyan tovább
EF könyvek
További info Bátyai Krisztián EF linkgyűjteménye http://goo.gl/Pk1MT Reiter István: Code First bevezető http://goo.gl/XT6DSE MVA: Implementing Entity Framework with MVC http://goo.gl/TtTXvv
Kérdések Köszönöm a figyelmet!