Erhalten Sie Zugang zu diesem und mehr als 300000 Büchern ab EUR 5,99 monatlich.
Schnell und einfach auf Daten zugreifen mit Entity Framework Core
Dieses Buch zeigt Ihnen, wie Sie mit der komplett überarbeiteten Version von Microsofts O/R-Mapper unterschiedliche Datenbanken auf moderne und zeitsparende Art und Weise ansprechen können. Profitieren Sie von höherer Geschwindigkeit, weniger RAM-Bedarf und Plattformunabhängigkeit.
Entity Framework Core-Kenntnisse vertiefen
Das Buch behandelt sowohl die Verwendung bestehender Datenbanken (Reverse Engineering) als auch die Generierung von Datenbankschemata aus Objektmodellen heraus (Forward Engineering).
Neben den Grundlagen lernen Sie auch, wie Sie mit Entity Framework Core
- den Aufwand für die Programmierung von Datenzugriffscode drastisch reduzieren,
- die Performance Ihrer Anwendungen optimieren und
- mobile Apps schreiben können.
Das Buch richtet sich an Softwareentwickler, die bereits grundlegende Erfahrung mit .NET, insbesondere C#, ADO.NET und LINQ, sowie mit relationalen Datenbanken gesammelt haben und nun Entity Framework Core zur Erstellung von Datenzugriffscode einsetzen wollen.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 418
Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:
Holger Schwichtenberg
Effizienter Datenzugriff mit Entity Framework Core
Datenbankprogrammierung mit C# für .NET Framework, .NET Core und Xamarin
Der Autor:
Dr. Holger Schwichtenberg, Essen www.IT-Visions.de
Alle in diesem Buch enthaltenen Informationen, Verfahren und Darstellungen wurden nach bestem Wissen zusammengestellt und mit Sorgfalt getestet. Dennoch sind Fehler nicht ganz auszuschließen. Aus diesem Grund sind die im vorliegenden Buch enthaltenen Informationen mit keiner Verpflichtung oder Garantie irgendeiner Art verbunden. Autor und Verlag übernehmen infolgedessen keine juristische Verantwortung und werden keine daraus folgende oder sonstige Haftung übernehmen, die auf irgendeine Art aus der Benutzung dieser Informationen – oder Teilen davon – entsteht.
Ebenso übernehmen Autor und Verlag keine Gewähr dafür, dass beschriebene Verfahren usw. frei von Schutzrechten Dritter sind. Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Buch berechtigt deshalb auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen und MarkenschutzGesetzgebung als frei zu betrachten wären und daher von jedermann benutzt werden dürften.
Bibliografische Information der Deutschen Nationalbibliothek: Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.
Dieses Werk ist urheberrechtlich geschützt. Alle Rechte, auch die der Übersetzung, des Nachdruckes und der Vervielfältigung des Buches, oder Teilen daraus, vorbehalten. Kein Teil des Werkes darf ohne schriftliche Genehmigung des Verlages in irgendeiner Form (Fotokopie, Mikrofilm oder ein anderes Verfahren) – auch nicht für Zwecke der Unterrichtsgestaltung – reproduziert oder unter Verwendung elektronischer Systeme verarbeitet, vervielfältigt oder verbreitet werden.
© 2018 Carl Hanser Verlag Münchenwww.hanser-fachbuch.de
Lektorat: Sylvia Hasselbach Copyediting: Matthias Bloch, Essen Umschlagdesign: Marc Müller-Bremer, München, www.rebranding.de Umschlagrealisation: Stephan Rönigk
Print-ISBN 978-3-446-44898-8 E-Book-ISBN 978-3-446-44978-7
Verwendete Schriften: SourceSansPro und SourceCodePro (Lizenz) CSS-Version: 1.0
Titelei
Impressum
Inhalt
Vorwort
Über den Autor
1 Einleitung
1.1 Programmiersprache in diesem Buch
1.2 Fallbeispiele in diesem Buch
1.2.1 Entitäten
1.3 Anwendungsarten in diesem Buch
1.4 Hilfsroutinen zur Konsolenausgabe
1.5 Programmcodebeispiel zum Download
2 Was ist Entity Framework Core?
2.1 Was ist ein Objekt-Relationaler Mapper?
2.2 ORM in der .NET-Welt
2.3 Versionsgeschichte von Entity Framework Core
2.4 Unterstützte Betriebssysteme
2.5 Unterstützte .NET-Versionen
2.6 Unterstützte Visual Studio-Versionen
2.7 Unterstützte Datenbanken
2.8 Funktionsumfang von Entity Framework Core
2.9 Funktionen, die dauerhaft entfallen
2.10 Funktionen, die Microsoft bald nachrüsten will
2.11 Hohe Priorität, aber nicht kritisch
2.12 Neue Funktionen in Entity Framework Core
2.13 Einsatzszenarien
3 Installation von Entity Framework Core
3.1 Nuget-Pakete
3.2 Paketinstallation
3.3 Aktualisierung auf eine neue Version
4 Konzepte von Entity Framework Core
4.1 Vorgehensmodelle bei Entity Framework Core
4.2 Artefakte bei Entity Framework Core
5 Reverse Engineering bestehender Datenbanken
5.1 Reverse Engineering mit PowerShell-Befehlen
5.2 Codegenerierung
5.3 .NET Core-Tool
5.4 Schwächen des Reverse Engineering
6 Forward Engineering für neue Datenbanken
6.1 Regeln für die selbsterstellten Entitätsklassen
6.1.1 Properties
6.1.2 Datentypen
6.1.3 Beziehungen (Master-Detail)
6.1.4 Vererbung
6.1.5 Primärschlüssel
6.1.6 Beispiele
6.2 Regeln für die selbsterstellte Kontextklasse
6.2.1 Nuget-Pakete
6.2.2 Basisklasse
6.2.3 Konstruktor
6.2.4 Beispiel
6.2.5 Provider und Verbindungszeichenfolge
6.2.6 Eigene Verbindungen
6.2.7 Thread-Sicherheit
6.3 Regeln für die Datenbankschemagenerierung
6.4 Beispiel-Client
6.5 Anpassung per Fluent-API (OnModelCreating())
6.6 Das erzeugte Datenmodell
7 Anpassung des Datenbankschemas
7.1 Persistente versus transiente Klassen
7.2 Namen im Datenbankschema
7.3 Reihenfolge der Spalten in einer Tabelle
7.4 Spaltentypen/Datentypen
7.5 Pflichtfelder und optionale Felder
7.6 Feldlängen
7.7 Primärschlüssel
7.8 Beziehungen und Fremdschlüssel
7.9 Optionale Beziehungen und Pflichtbeziehungen
7.10 Uni- und Bidirektionale Beziehungen
7.11 1:1-Beziehungen
7.12 Indexe festlegen
7.13 Weitere Syntaxoptionen für das Fluent-API
7.13.1 Sequentielle Konfiguration
7.13.2 Strukturierung durch Statement Lambdas
7.13.3 Strukturierung durch Unterroutinen
7.13.4 Strukturierung durch Konfigurationsklassen
7.14 Massenkonfiguration mit dem Fluent-API
8 Datenbankschemamigrationen
8.1 Anlegen der Datenbank zur Laufzeit
8.2 Schemamigrationen zur Entwicklungszeit
8.3 Befehle für die Schemamigrationen
8.4 ef.exe
8.5 Add-Migration
8.6 Update-Database
8.7 Script-Migration
8.8 Weitere Migrationsschritte
8.9 Migrationsszenarien
8.10 Weitere Möglichkeiten
8.11 Schemamigrationen zur Laufzeit
9 Daten lesen mit LINQ
9.1 Kontextklasse
9.2 LINQ-Abfragen
9.3 Schrittweises Zusammensetzung von LINQ-Abfragen
9.4 Repository-Pattern
9.5 Einsatz von var
9.6 LINQ-Abfragen mit Paging
9.7 Projektionen
9.8 Abfrage nach Einzelobjekten
9.9 Laden anhand des Primärschlüssels mit Find()
9.10 LINQ im RAM statt in der Datenbank
9.11 Umgehung für das GroupBy-Problem
9.11.1 Mapping auf Nicht-Entitätstypen
9.11.2 Entitätsklasse für die Datenbanksicht anlegen
9.11.3 Einbinden der Entitätsklasse in die Kontextklasse
9.11.4 Verwendung der Pseudo-Entitätsklasse
9.11.5 Herausforderung: Migrationen
9.11.6 Gruppierungen mit Datenbanksichten
9.12 Kurzübersicht über die LINQ-Syntax
9.12.1 Einfache SELECT-Befehle (Alle Datensätze)
9.12.2 Bedingungen (where)
9.12.3 Bedingungen mit Mengen (in)
9.12.4 Sortierungen (orderby)
9.12.5 Paging (Skip() und Take())
9.12.6 Projektion
9.12.7 Aggregatfunktionen (Count(), Min(), Max(), Average(), Sum())
9.12.8 Gruppierungen (GroupBy)
9.12.9 Einzelobjekte (SingleOrDefault(), FirstOrDefault())
9.12.10 Verbundene Objekte (Include())
9.12.11 Inner Join (Join)
9.12.12 Cross Join (Kartesisches Produkt)
9.12.13 Join mit Gruppierung
9.12.14 Unter-Abfragen (Sub-Select)
10 Objektbeziehungen und Ladestrategien
10.1 Standardverhalten
10.2 Kein Lazy Loading
10.3 Eager Loading
10.4 Explizites Nachladen (Explicit Loading)
10.5 Preloading mit Relationship Fixup
10.6 Details zum Relationship Fixup
11 Einfügen, Löschen und Ändern
11.1 Speichern mit SaveChanges()
11.2 Änderungsverfolgung auch für Unterobjekte
11.3 Das Foreach-Problem
11.4 Objekte hinzufügen mit Add()
11.5 Verbundene Objekte anlegen
11.6 Verbundene Objekte ändern/Relationship Fixup
11.7 Widersprüchliche Beziehungen
11.8 Zusammenfassen von Befehlen (Batching)
11.9 Objekte löschen mit Remove()
11.10 Löschen mit einem Attrappen-Objekt
11.11 Massenlöschen
11.12 Datenbanktransaktionen
11.13 Change Tracker abfragen
11.13.1 Zustand eines Objekts
11.13.2 Liste aller geänderten Objekte
12 Datenänderungskonflikte (Concurrency)
12.1 Rückblick
12.2 Im Standard keine Konflikterkennung
12.3 Optimistisches Sperren/Konflikterkennung
12.4 Konflikterkennung für alle Eigenschaften
12.5 Konflikteinstellung per Konvention
12.6 Fallweise Konflikteinstellung
12.7 Zeitstempel (Timestamp)
12.8 Konflikte auflösen
12.9 Pessimistisches Sperren bei Entity Framework Core
13 Protokollierung (Logging)
13.1 Verwendung der Erweiterungsmethode Log()
13.2 Implementierung der Log()-Erweiterungsmethode
13.3 Protokollierungskategorien
14 Asynchrone Programmierung
14.1 Asynchrone Erweiterungsmethoden
14.2 ToListAsync()
14.3 SaveChangesAsync()
14.4 ForeachAsync()
15 Dynamische LINQ-Abfragen
15.1 Schrittweises Zusammensetzen von LINQ-Abfragen
15.2 Expression Trees
15.3 Dynamic LINQ
16 Daten lesen und ändern mit SQL, Stored Procedures und Table Valued Functions
16.1 Abfragen mit FromSql()
16.2 Zusammensetzbarkeit von LINQ und SQL
16.3 Globale Abfragefilter bei SQL-Abfragen (ab Version 2.0)
16.4 Stored Procedures und Table Valued Functions
16.5 Globale Abfragefilter bei Stored Procedures und Table Valued Functions
16.6 Nicht-Entitätsklassen als Ergebnismenge
16.7 SQL-DML-Befehle ohne Resultset
17 Weitere Tipps und Tricks zum Mapping
17.1 Shadow Properties
17.1.1 Automatische Shadow Properties
17.1.2 Festlegung eines Shadow Property
17.1.3 Ausgabe aller Shadow Properties einer Entitätsklasse
17.1.4 Lesen und Ändern eines Shadow Property
17.1.5 LINQ-Abfragen mit Shadow Properties
17.1.6 Praxisbeispiel: Automatisches Setzen des Shadow Property bei jedem Speichern
17.2 Tabellenaufteilung (Table Splitting)
17.3 Berechnete Spalten (Computed Columns)
17.3.1 Automatisches SELECT
17.3.2 Praxistipp: Spalten mit einer Berechnungsformel anlegen
17.3.3 Spalten mit einer Berechnungsformel nutzen
17.3.4 Spalten mit einer Berechnungsformel beim Reverse Engineering
17.4 Standardwerte (Default Values)
17.4.1 Standardwerte beim Forward Engineering festlegen
17.4.2 Standardwerte verwenden
17.4.3 Praxistipp: Standardwerte schon beim Anlegen des Objekts vergeben
17.4.4 Standardwerte beim Reverse Engineering
17.5 Sequenzobjekte (Sequences)
17.5.1 Erstellen von Sequenzen beim Forward Engineering
17.5.2 Sequenzen im Einsatz
17.6 Alternative Schlüssel
17.6.1 Alternative Schlüssel definieren
17.6.2 Alternative Schlüssel im Einsatz
17.7 Kaskadierendes Löschen (Cascading Delete)
17.8 Abbildung von Datenbanksichten (Views)
17.8.1 Datenbanksicht anlegen
17.8.2 Entitätsklasse für die Datenbanksicht anlegen
17.8.3 Einbinden der Entitätsklasse in die Kontextklasse
17.8.4 Verwendung der Datenbanksicht
17.8.5 Herausforderung: Migrationen
18 Weitere Tipps und Tricks zu LINQ
18.1 Globale Abfragefilter (ab Version 2.0)
18.1.1 Filter definieren
18.1.2 Filter nutzen
18.1.3 Praxistipp: Filter ignorieren
18.2 Zukünftige Abfragen (Future Queries)
19 Leistungsoptimierung (Performance Tuning)
19.1 Vorgehensmodell zur Leistungsoptimierung bei Entity Framework Core
19.2 Best Practices für Ihre eigenen Leistungstests
19.3 Leistungsvergleich verschiedener Dattenzugriffstechniken in .NET
19.4 Objektzuweisung optimieren
19.5 Massenoperationen
19.5.1 Einzellöschen
19.5.2 Optimierung durch Batching
19.5.3 Löschen ohne Laden mit Pseudo-Objekten
19.5.4 Einsatz von klassischem SQL anstelle des Entity Framework Core-APIs
19.5.5 Lamdba-Ausdrücke für Massenlöschen mit EFPlus
19.5.6 Massenaktualisierung mit EFPlus
19.6 Leistungsoptimierung durch No-Tracking
19.6.1 No-Tracking aktivieren
19.6.2 No-Tracking fast immer möglich
19.6.3 No-Tracking im änderbaren Datagrid
19.6.4 QueryTrackingBehavior und AsTracking()
19.6.5 Best Practices
19.7 Auswahl der besten Ladestrategie
19.8 Zwischenspeicherung (Caching)
19.8.1 MemoryCache
19.8.2 Abstraktion CacheManager
19.9 Second-Level-Caching mit EFPlus
19.9.1 Einrichten des Second-Level-Cache
19.9.2 Verwenden des Second-Level-Cache
20 Softwarearchitektur mit Entity Framework Core
20.1 Monolithisches Modell
20.2 Entity Framework Core als Datenzugriffsschicht
20.3 Reine Geschäftslogik
20.4 Geschäftsobjekt- und ViewModel-Klassen
20.5 Verteilte Systeme
20.6 Fazit
21 Zusatzwerkzeuge
21.1 Entity Framework Core Power Tools
21.1.1 Funktionsüberblick
21.1.2 Reverse Engineering mit Entity Framework Core Power Tools
21.1.3 Diagramme mit Entity Framework Core Power Tools
21.2 LINQPad
21.2.1 Aufbau von LINQPad
21.2.2 Datenquellen einbinden
21.2.3 LINQ-Befehle ausführen
21.2.4 Speichern
21.2.5 Weitere LINQPad-Treiber
21.2.6 Interaktive Programmcodeeingabe
21.2.7 Fazit zu LINQPad
21.3 Entity Developer
21.3.1 Reverse Engineering mit Entity Developer
21.3.2 Forward Engineering mit Entity Developer
21.4 Entity Framework Profiler
21.4.1 Einbinden des Entity Framework Profilers
21.4.2 Befehle überwachen mit Entity Framework Profiler
21.4.3 Warnungen vor potenziellen Problemen
21.4.4 Analysefunktionen
21.4.5 Fazit zu Entity Framework Profiler
22 Zusatzkomponenten
22.1 Entity Framework Plus (EFPlus)
22.2 Second-Level-Caching mit EFSecondLevelCache.Core
22.3 Objekt-Objekt-Mapping und AutoMapper
22.3.1 Objekt-Objekt-Mapping per Reflection
22.3.2 AutoMapper
22.3.3 Beispiel
22.3.4 Abbildungen konfigurieren
22.3.5 Abbildung ausführen mit Map()
22.3.6 Abbildungskonventionen
22.3.7 Profilklassen
22.3.8 Verbundene Objekte
22.3.9 Manuelle Abbildungen
22.3.10 Typkonvertierungen
22.3.11 Objektmengen
22.3.12 Vererbung
22.3.13 Generische Klassen
22.3.14 Zusatzaktionen vor und nach dem Mapping
22.3.15 Geschwindigkeit
22.3.16 Fazit zu AutoMapper
23 Praxislösungen
23.1 Entity Framework Core in einer ASP.NET Core-Anwendung
23.1.1 Das Fallbeispiel „MiracleList“
23.1.2 Architektur
23.1.3 Entitätsklassen
23.1.4 Entity Framework Core-Kontextklasse
23.1.5 Lebensdauer der Kontextklasse in ASP.NET Core-Anwendungen
23.1.6 Geschäftslogik
23.1.7 WebAPI
23.1.8 Verwendung von Entity Framework Core per Dependency Injection
23.1.9 Praxistipp: Kontextinstanzpooling (DbContext Pooling)
23.2 Entity Framework Core in einer Universal Windows Platform App
23.2.1 Das Fallbeispiel „MiracleList Light“
23.2.2 Architektur
23.2.3 Entitätsklassen
23.2.4 Entity Framework Core-Kontextklasse
23.2.5 Startcode
23.2.6 Erzeugte Datenbank
23.2.7 Datenzugriffscode
23.2.8 Benutzeroberfläche
23.3 Entity Framework Core in einer Xamarin-Cross-Platform-App
23.3.1 Das Fallbeispiel „MiracleList Light“
23.3.2 Architektur
23.3.3 Entitätsklassen
23.3.4 Entity Framework Core-Kontextklasse
23.3.5 Startcode
23.3.6 Erzeugte Datenbank
23.3.7 Datenzugriffscode
23.3.8 Benutzeroberfläche
23.4 N:M-Beziehungen zu sich selbst
24 Quellen im Internet
Liebe Leserinnen und Leser,
ich nutze Entity Framework in echten Softwareentwicklungsprojekten seit der allerersten Version, also seit der Version 1.0 von ADO.NET Entity Framework im Jahr 2008. Zuvor hatte ich einen selbstentwickelten Objekt-Relationalen Mapper in meinen Projekten verwendet. Entity Framework Core ist das Nachfolgeprodukt, das es seit 2016 gibt. Ich setzte seitdem auch (aber nicht ausschließlich) Entity Framework Core in der Praxis ein. Viele Projekte laufen noch mit dem klassischen Entity Framework.
Microsoft entwickelt Entity Framework Core inkrementell, d. h. die Versionen 1.x und 2.x stellen zunächst eine in vielen Punkten noch unvollständige Grundversion dar, die in den Folgeversionen dann komplettiert wird.
Dieses inkrementelle Konzept habe ich auch mit diesem Buch umgesetzt. Das Buch ist seit September 2016 in mehreren Versionen erschienen. Die vor Ihnen liegende Version dieses Buchs beschreibt nun alle Kernaspekte und viele Tipps und Tricks sowie Praxisszenarien zu Entity Framework Core. Ich plane, in Zukunft weitere Versionen dieses Buchs zu veröffentlichen, die die kommenden Versionen von Entity Framework Core beschreiben und auch weitere Tipps & Tricks sowie Praxisszenarien ergänzen.
Da Fachbücher leider heutzutage nicht nennenswert dazu beitragen können, den Lebensunterhalt meiner Familie zu bestreiten, ist dieses Projekt ein Hobby. Dementsprechend kann ich nicht garantieren, wann es Updates zu diesem Buch geben wird. Ich werde dann an diesem Buch arbeiten, wenn ich neben meinem Beruf als Softwarearchitekt, Berater und Dozent und meinen sportlichen Betätigungen noch etwas Zeit für das Fachbuchautorenhobby übrig habe.
Zudem möchte ich darauf hinweisen, dass ich natürlich keinen kostenfreien technischen Support zu den Inhalten dieses Buchs geben kann. Ich freue mich aber immer über konstruktives Feedback und Verbesserungsvorschläge. Bitte verwenden Sie dazu das Kontaktformular auf www.dotnet-doktor.de.
Wenn Sie technische Hilfe zu Entity Framework und Entity Framework Core oder anderen Themen rund um .NET, Visual Studio, Windows oder andere Microsoft-Produkte benötigen, stehe ich Ihnen im Rahmen meiner beruflichen Tätigkeit für die Firmen www.IT-Visions.de (Beratung, Schulung, Support) und 5Minds IT-Solutions GmbH & Co KG (Softwareentwicklung, siehe www.5minds.de) gerne zur Verfügung. Bitte wenden Sie sich für ein Angebot an das jeweilige Kundenteam.
Die Beispiele zu diesem Buch können Sie herunterladen auf der von mir ehrenamtlich betriebenen Leser-Website unter www.IT-Visions.de/Leser. Dort müssen Sie sich registrieren. Bei der Registrierung wird ein Losungswort abgefragt. Bitte geben Sie dort Ascension ein.
Herzliche Grüße aus Essen, dem Herzen der Metropole Ruhrgebiet
Holger Schwichtenberg
Studienabschluss Diplom-Wirtschaftsinformatik an der Universität Essen
Promotion an der Universität Essen im Gebiet komponentenbasierter Softwareentwicklung
Seit 1996 selbstständig als unabhängiger Berater, Dozent, Softwarearchitekt und Fachjournalist
Leiter des Berater- und Dozententeams
bei www.IT-Visions.de
Leitung der Softwareentwicklung im Bereich Microsoft/.NET
bei der 5minds IT-Solutions GmbH & Co. KG (www.5minds.de)
Über 65 Fachbücher beim Carl Hanser Verlag, bei O’Reilly, Microsoft Press und Addison-Wesley sowie mehr als 950 Beiträge in Fachzeitschriften
Gutachter in den Wettbewerbsverfahren der EU gegen Microsoft (2006-2009)
Ständiger Mitarbeiter der Zeitschriften iX (seit 1999), dotnetpro (seit 2000) und Windows Developer (seit 2010) sowie beim Online-Portal heise.de (seit 2008)
Regelmäßiger Sprecher auf nationalen und internationalen Fachkonferenzen (z. B. Microsoft TechEd, Microsoft Summit, Microsoft IT Forum, BASTA, BASTA-on-Tour, .NET Architecture Camp, Advanced Developers Conference, Developer Week, OOP, DOTNET Cologne, MD DevDays, Community in Motion, DOTNET-Konferenz, VS One, NRW.Conf, Net.Object Days, Windows Forum, Container Conf)
Zertifikate und Auszeichnungen von Microsoft:
Microsoft Most Valuable Professional (MVP)
Microsoft Certified Solution Developer (MCSD)
Thematische Schwerpunkte:
Softwarearchitektur, mehrschichtige Softwareentwicklung, Softwarekomponenten, SOA
Microsoft .NET Framework, Visual Studio, C#, Visual Basic
.NET-Architektur/Auswahl von .NET-Technologien
Einführung von .NET Framework und Visual Studio/Migration auf .NET
Webanwendungsentwicklung und Cross-Plattform-Anwendungen mit HTML, ASP.NET, JavaScript/TypeScript und Webframeworks wie Angular
Enterprise .NET, verteilte Systeme/Webservices mit .NET, insbesondere Windows Communication Foundation und WebAPI
Relationale Datenbanken, XML, Datenzugriffsstrategien
Objektrelationales Mapping (ORM), insbesondere ADO.NET Entity Framework und EF Core
Windows PowerShell, PowerShell Core und Windows Management Instrumentation (WMI)
Ehrenamtliche Community-Tätigkeiten:
Vortragender für die International .NET Association (INETA)
Betrieb diverser Community-Websites: www.dotnetframework.de, www.entwickler-lexikon.de, www.windows-scripting.de, www.aspnetdev.de u. a.
Firmenwebsites: http://www.IT-Visions.de und http://www.5minds.de
Weblog: http://www.dotnet-doktor.de
Kontakt: E-Mail [email protected] sowie Telefon 0201-64 95 90-0
Entity Framework Core ist ein Objekt-Relationaler Mapper (ORM) für .NET (.NET Framework, .NET Core, Mono und Xamarin). Entity Framework Core ist eine Neuimplementierung des „ADO.NET Entity Framework“.
Zusammen mit .NET Core Version 1.0 und ASP.NET Core Version 1.0 ist auch Entity Framework Core Version 1.0 am 27. Juni 2016 erstmals erschienen. Die neue Variante von Microsofts Objekt-Relationalem Mapper enthält in den ersten Versionen allerdings noch einige gravierende Lücken, die den Einsatzbereich beschränken. Die Version 2.0 ist am 14. August 2017 erschienen. Version 2.1 ist in Arbeit.
In der Datenbankwelt sind relationale Datenbanken vorherschend, in der Programmierwelt sind es Objekte. Zwischen den beiden Welten gibt es erhebliche semantische und syntaktische Unterschiede, die man unter dem Begriff „Impedance Mismatch“ (zu deutsch: Unverträglichkeit, vgl. [https://dict.leo.org/englisch-deutsch/impedance%20mismatch]) oder „Semantic Gap“ (zu deutsch: semantische Lücke) zusammenfasst.
Kern des objektorientierten Programmierens (OOP) ist die Arbeit mit Objekten als Instanzen von Klassen im Hauptspeicher. Die meisten Anwendungen beinhalten dabei auch die Anforderung, in Objekten gespeicherte Daten dauerhaft zu speichern, insbesondere in Datenbanken. Grundsätzlich existieren objektorientierte Datenbanken (OODB), die direkt in der Lage sind, Objekte zu speichern. Allerdings haben objektorientierte Datenbanken bisher nur eine sehr geringe Verbreitung. Der vorherrschende Typus von Datenbanken sind relationale Datenbanken, die Datenstrukturen jedoch anders abbilden als Objektmodelle.
Um die Handhabung von relationalen Datenbanken in objektorientierten Systemen natürlicher zu gestalten, setzt die Software-Industrie seit Jahren auf O/R-Mapper (auch: OR-Mapper oder ORM geschrieben). O steht dabei für objektorientiert und R für relational. Diese Werkzeuge bilden demnach Konzepte aus der objektorientierten Welt, wie Klassen, Attribute oder Beziehungen zwischen Klassen, auf entsprechende Konstrukte der relationalen Welt, wie zum Beispiel Tabellen, Spalten und Fremdschlüssel, ab. Der Entwickler kann somit in der objektorientierten Welt verbleiben und den O/R-Mapper anweisen, bestimmte Objekte, welche in Form von Datensätzen in den Tabellen der relationalen Datenbank vorliegen, zu laden bzw. zu speichern. Wenig interessante und fehleranfällige Aufgaben wie das manuelle Erstellen von INSERT-, UPDATE- oder DELETE-Anweisungen übernimmt der O/R-Mapper hierbei ebenfalls, was zu einer weiteren Entlastung des Entwicklers führt.
Bild 2.1Beim ORM bildet man Konstrukte der OOP-Welt auf die relationale Welt ab.
Zwei besonders hervorstechende Unterschiede zwischen Objektmodell und Relationenmodell sind N:M-Beziehungen und Vererbung. Während man in einem Objektmodell eine N:M-Beziehung zwischen Objekten durch eine wechselseitige Objektmenge abbilden kann, benötigt man in der relationalen Datenbank eine Zwischentabelle. Vererbung kennen relationale Datenbanken gar nicht. Hier gibt es verschiedene Möglichkeiten der Nachbildung, doch dazu später mehr.
Wenn ein .NET-Entwickler aus einer Datenbank mit einem DataReader oder DataSet Daten einliest, dann betreibt er noch kein OR Mapping. DataReader und DataSet sind zwar .NET-Objekte, aber diese verwalten nur Tabellenstrukturen. DataReader und DataSet sind aus der Sicht eines Objektmodells untypisierte, unspezifische Container. Erst wenn ein Entwickler spezifische Klassen für die in den Tabellen gespeicherten Strukturen definiert und die Inhalte aus DataSet oder DataReader in diese spezifischen Datenstrukturen umkopiert, betreibt er OR Mapping. Solch ein „händisches OR Mapping“ ist für den Lesezugriff (gerade bei sehr breiten Tabellen) eine sehr aufwändige, mühselige und eintönige Programmierarbeit. Will man dann Änderungen in den Objekten auch noch wieder speichern, wird die Arbeit allerdings zur intellektuellen Herausforderung. Denn man muss erkennen können, welche Objekte verändert wurden, da man sonst ständig alle Daten aufs Neue speichert, was in Mehrbenutzerumgebungen ein Unding ist.
Während in der Java-Welt das ORM-Werkzeug schon sehr lange zu den etablierten Techniken gehört, hat Microsoft diesen Trend lange verschlafen bzw. es nicht vermocht, ein geeignetes Produkt zur Marktreife zu führen. ADO.NET in .NET 1.0 bis 3.5 enthielt keinen ORM, sondern beschränkte sich auf den direkten Datenzugriff und die Abbildung zwischen XML-Dokumenten und dem relationalen Modell.
Viele .NET-Entwickler haben sich daher daran gesetzt, diese Arbeit mit Hilfsbibliotheken und Werkzeugen zu vereinfachen. Dies war die Geburtsstunde einer großen Vielfalt von ORM-Werkzeugen für .NET. Dabei scheint es so, dass viele .NET-Entwickler das geflügelte Wort, dass ein Mann in seinem Leben einen Baum gepflanzt, ein Kind gezeugt und ein Haus gebaut haben sollte, um den Punkt „einen OR-Mapper geschrieben“ ergänzt haben (wobei der Autor dieses Buchs sich davon auch nicht freisprechen kann, weil er ebenfalls einen OR-Mapper geschrieben hat). Anders ist die Vielfalt der ähnlichen Lösungen kaum erklärbar. Neben den öffentlich bekannten ORM-Werkzeugen für .NET findet man in den Unternehmen zahlreiche hauseigene Lösungen.
Bekannte öffentliche ORM für .NET von Drittanbietern (z. T. Open Source) sind:
nHibernate
Telerik Data Access (alias Open Access)
Genome
LLBLGen Pro
Wilson
Subsonic
OBJ.NET
.NET Data Objects (NDO)
Dapper
PetaPoco
Massive
Developer Express XPO
Neben den aktiven Entwicklern von ORM-Werkzeugen für .NET und den passiven Nutzern gibt eine noch größere Fraktion von Entwicklern, die ORM bisher nicht einsetzen. Meist herrscht Unwissenheit, die auch nicht aufgearbeitet wird, denn es herrscht das Motto „Wenn Microsoft es nicht macht, ist es auch nicht wichtig!“
Mit LINQ-to-SQL und dem ADO.NET Entity Framework sowie Entity Framework bietet Microsoft selbst jedoch inzwischen sogar drei verschiedene Produkte an. Der Softwarekonzern hat aber inzwischen verkündet, dass sich die Weiterentwicklungsbemühungen allein auf das Entity Framework Core konzentieren.
Die folgende Tabelle zeigt die Versionsgeschichte von Entity Framework Core.
Bild 2.2Entity Framework Core-Versionsgeschichte
[Quelle: https://www.nuget.org/packages/Microsoft.EntityFrameworkCore]
Versionsnummernänderungen an der dritten Stelle (z. B. 1.0.1 und 1.0.2) enthalten nur Fehlerbehebungen. Bei Versionsnummernänderungen an der zweiten Stelle sind auch neue Funktionen enthalten. In diesem Buch wird darauf hingewiesen, wenn eine Funktion besprochen wird, die eine bestimmte Versionsnummer voraussetzt.
HINWEIS: Die endgültige Version der Entity Framework Core-Werkzeuge für Entity Framework Core 1.x ist erst am 6.3.2017 im Rahmen von Entity Framework Core 1.1.1 und Visual Studio 2017 erschienen. Zuvor gab es nur „Preview“-Versionen. Seit Entity Framework Core 2.0 werden die Werkzeuge immer mit den neuen Produktreleases ausgeliefert.
Genau wie die anderen Produkte der Core-Produktfamilie ist das Entity Framework Core (früherer Name: Entity Framework 7.0) ebenfalls plattformunabhängig. Die Core-Variante des etablierten Objekt-Relationalen Mappers läuft nicht nur auf dem .NET „Full“ Framework, sondern auch auf .NET Core und Mono inklusive Xamarin. Damit kann man Entity Framework Core auf Windows, Windows Phone/Mobile, Linux, MacOS, iOS und Android nutzen.
Entity Framework Core 1.x läuft auf .NET Core 1.x, .NET Framework ab Version 4.5.1, Mono ab Version 4.6, Xamarin.iOS ab Version 10, Xamarin Android ab Version 7.0 und der Windows Univeral Platform (UWP).
Entity Framework Core 2.0 basiert auf .NET Standard 2.0 und setzt daher eine der folgenden .NET-Implementierungen voraus:
.NET Core 2.0 (oder höher)
.NET Framework 4.6.1 (oder höher)
Mono 5.4 (oder höher)
Xamarin.iOS 10.14 (oder höher)
Xamarin.Mac 3.8 (oder höher)
Xamarin.Android 7.5 (oder höher)
Universal Windows Platform (UWP) 10.0.16299 (oder höher)
Bild 2.3Implementierungen von .NET Standard
[Quelle: https://docs.microsoft.com/de-de/dotnet/standard/library]
HINWEIS: Microsoft begründet die Beschränkung auf .NET Standard in Entity Framework Core 2.0 in [https://github.com/aspnet/Announcements/issues/246]. Unter anderem kann dadurch die Größe der Nuget-Pakete deutlich reduziert werden.
Für die Nutzung von Entity Framework Core 2.0 benötigt man zwingend Visual Studio 2017 Update 3 oder höher, auch wenn man mit dem klassischen .NET Framework programmiert, da Visual Studio nur mit diesem Update .NET Standard 2.0 kennt und versteht, dass .NET Framework 4.6.1 und höher Implementierungen von .NET Standard 2.0 sind.
Wenn man für .NET Core programmiert, benötigt man für Entity Framework Core 1.x Visual Studio 2017, (die Werkzeuge für Visual Studio 2015 sind veraltert und werden von Microsoft nicht mehr aktualisiert). Für Entity Framework Core 1.x in Verbindung mit dem klassischen .NET Framework reicht auch eine ältere Visual Studio-Version.
Die folgende Tabelle zeigt die von Entity Framework Core durch Microsoft (SQL Server, SQL Compact und SQLite von Microsoft) und Drittanbieter (PostgreSQL, DB2, Oracle, MySQL u. a.) unterstützten Datenbankmanagementsysteme.
Auf Mobilgeräten mit Xamarin bzw. im Rahmen von Windows 10 Universal Platform Apps konnte Entity Framework Core 1.x nur lokale Datenbanken (SQLite) ansprechen. Mit der Einführung von .NET Standard 2.0 steht nun der Microsoft SQL Server-Client auch auf Xamarin und der Windows 10 Universal Platform (ab dem Herbst 2017 Creators Update) zur Verfügung.
Die geplante Unterstützung für NoSQL-Datenbanken wie Redis und Azure Table Storage ist in Version 1.x/2.x von Entity Framework Core noch nicht enthalten. Es gibt aber für MongoDB ein Entwicklungsprojekt auf Github [https://github.com/crhairr/EntityFrameworkCore.MongoDb].
Tabelle 2.1 Verfügbare Datenbanktreiber für Entity Framework Core
Datenbank
Anbieter / Preis
URL
Microsoft SQL Server
Microsoft / kostenfrei
www.nuget.org/packages/Microsoft.EntityFrameworkCore.SqlServer
Microsoft SQL Server Compact 3.5
Microsoft / kostenfrei
www.nuget.org/packages/Entity FrameworkCore.SqlServerCom pact35
Microsoft SQL Server Compact 4.0
Microsoft / kostenfrei
www.nuget.org/packages/Entity FrameworkCore.SqlServerCom pact40
SQLite
Microsoft / kostenfrei
www.nuget.org/packages/Microsoft.EntityFrameworkCore.Sqlite
In-Memory
Microsoft / kostenfrei
www.nuget.org/packages/Microsoft.EntityFrameworkCore.InMemory
MySQL
Oracle / kostenfrei
www.nuget.org/packages/MySQL.Data.EntityFrameworkCore
PostgreSQL
Open Source-Team npgsql.org / kostenfrei
www.nuget.org/packages/Npgsql.EntityFrameworkCore.PostgreSQL
DB2
IBM / kostenfrei
www.nuget.org/packages/Entity Framework.IBMDataServer
MySQL, Oracle, PostgreSQL, SQLite, DB2, Salesforce, Dynamics CRM, SugarCRM, Zoho CRM, QuickBooks, FreshBooks, MailChimp, ExactTarget, Bigcommerce, Magento
Devart / kostenpflichtig(99 bis 299 Dollar pro Treiberart)
www.devart.com/purchase.html#dotConnect
ACHTUNG: Aufgrund von „Breaking Changes“ in den Provider-Schnittstellen, sind die Provider für Entity Framework Core 1.x nicht kompatibel zu Entity Framework Core 2.0. Man benötigt also für die Version 2.0 neue Provider!
Die Abbildung visualisiert, dass Entity Framework Core (gelb) gegenüber dem bisherigen Entity Framework (blau, aktuelle Version 6.1.3) einige neue Funktionen enthält (Bereich, der nur gelb, aber nicht blau ist). Es gibt aber auch einige Bereiche, die nur blau und nicht gelb sind: Das sind die Funktionen, die in Entity Framework 6.1.3 enthalten sind, aber nicht in Entity Framework Core 1.x/2.0. Microsoft wird einige Funktionen davon in den kommenden Versionen von Entity Framework Core nachrüsten, andere Funktionen werden für immer entfallen.
Bild 2.4Funktionsumfang des bisherigen Entity Framework im Vergleich zu Entity Framework Core. Links zeigt eine Sprechblase einige Features, die dauerhaft entfallen sind.
Folgende Funktionen hat Microsoft grundsätzlich gestrichen:
Die Vorgehensweise Database First und Model First. Es gibt nur noch das Code-based Modelling (früher Code First), mit dem man sowohl Programmcode aus Datenbanken erzeugen kann (Reverse Engineering) als auch Datenbanken aus Programmcode (Forward Engineering).
Das Entity Data Model (EDM) und die XML-Repräsentation davon (EDMX) entfallen. Bisher wurde auch beim Code First intern ein EDM im RAM erzeugt. Der Overhead entfällt.
Die Basisklasse ObjectContext für den Entity Framework-Kontext entfällt. Es gibt nur noch die Basisklasse DbContext. DbContext ist jetzt in Entity Framework Core kein Wrapper um ObjectContext mehr, sondern eine komplett eigenständige Implementierung.
Die Basisklasse EntityObject für Entitätsklassen entfällt. Die Entitätsklassen sind nun immer Plain Old CLR Objects (POCOs).
Auch die Abfragesprache Entity SQL (ESQL) entfällt. Es gibt nur noch Unterstützung für LINQ, SQL und Stored Procedures (SPs) sowie Table Valued Functions (TVFs).
Automatische Schemamigrationen werden nicht mehr angeboten. Schemamigrationen inklusive der Ersterstellung eines Datenbankschemas sind nun zur Entwicklungszeit immer manuell auszuführen. Zur Laufzeit kann eine Migration weiterhin beim ersten Zugriff auf die Datenbank erfolgen.
Einige Szenarien des komplexeren Mappings zwischen Tabellen und Typen entfallen. Dazu gehört das Multiple Entity Sets per Type (MEST, verschiedene Tabellen auf dieselbe Entität abbilden) und das Kombinieren der Strategien Table per Hierarchy (TPH), Table per Type (TPT) und Table per Concrete Type (TPC) in einer Vererbungshierarchie.
In der Roadmap für Entity Framework-Core [https://github.com/aspnet/EntityFramework/wiki/Roadmap] dokumentiert Microsoft-Entwickler Rowan Miller, welche Features in Entity Framework-Core fehlen, die man „bald“ nachrüsten will. Dabei ist dies nicht mit einem konkreten Zeitplan hinterlegt. Bemerkenswert ist, dass Microsoft einige dieser Funktionen selbst als „kritisch“ bezeichnet. Zu diesen „kritischen“ fehlenden Funktionen gehören:
Entity Framework Core unterstützt nur den Zugriff auf Tabellen, nicht aber auf Views (Sichten) in der Datenbank. Man kann Views nur nutzen, wenn man den View sowie den Programmcode manuell erstellt und den View wie eine Tabelle behandelt.
Stored Procedures können bisher nur zum Abfragen von Daten (SELECT), nicht aber zum Einfügen (INSERT), Aktualisieren (UPDATE) und Löschen (DELETE) verwendet werden.
Einige LINQ-Befehle werden derzeit nicht in der Datenbank, sondern im RAM ausgeführt. Dazu gehört auch der group by-Operator, d. h. bei allen Gruppierungen werden alle Datensätze aus der Datenbank ins RAM gelesen und dort gruppiert, was bei allen Tabellen (außer sehr kleinen) zu einer katastrophalen Performance führt.
Es gibt weder ein automatisches Lazy Loading noch ein explizites Nachladen im Entity Framework Core-API. Aktuell kann der Entwickler verbundene Datensätze nur direkt mitladen (Eager Loading) oder mit separaten Befehlen nachladen.
Direktes SQL und Stored Procedures können nur genutzt werden, wenn sie Entitätstypen zurückliefern. Andere Typen werden bisher nicht unterstützt.
Reverse Engineering bestehender Datenbanken kann man bisher nur von der Kommandozeile bzw. der Nuget-Konsole in Visual Studio starten. Den GUI-basierten Assistenten gibt es nicht mehr.
Es gibt auch kein „Update Model from Database“ für bestehende Datenbanken, d. h. nach einem Reverse Engineering einer Datenbank muss der Entwickler Datenbankschemaänderungen im Objektmodell manuell nachtragen oder das ganze Objektmodell neu generieren. Diese Funktion gab es aber auch bisher schon bei Code First nicht, sondern nur bei Database First.
Komplexe Typen (Complex Types), also Klassen, die keine eigene Entität, sondern Teil einer anderen Entität darstellen, gibt es nicht.
In einer zweiten Liste nennt Microsoft weitere Funktionen, die sie nicht als kritisch ansehen, die aber dennoch „hohe Priorität“ haben:
Es gibt bisher keine grafische Visualisierung eines Objektmodells, wie das bislang bei EDMX möglich war.
Einige der bisher vorhandenen Typkonvertierungen, z. B. zwischen XML und String, gibt es noch nicht.
Die Geo-Datentypen Geography und Geometry von Microsoft SQL Server werden bisher nicht unterstützt.
Entity Framework Core unterstützt keine N:M-Abbildungen: Bisher muss der Entwickler dies mit zwei 1:N-Abbildung und einer Zwischenentität analog zur Zwischentabelle in der Datenbank nachbilden.
Table per Type wird bislang nicht als Vererbungsstrategie unterstützt. Entity Framework Core verwendet TPH, wenn es für die Basisklasse ein DBSet<T> gibt, sonst TPC. TPC kann man nicht explizit konfigurieren.
Das Befüllen der Datenbank mit Daten im Rahmen der Migration (Seed()-Funktion) ist nicht möglich.
Die mit Entity Framework 6.0 eingeführten Command Interceptors, mit denen ein Softwareentwickler von Entity Framework zur Datenbank gesendete Befehle vor und nach der Ausführung in der Datenbank beeinflussen kann, gibt es noch nicht.
Einige Punkte auf dieser High Priority-Liste von Microsoft sind zudem auch neue Features, die Entity Framework 6.1.3 selbst (noch) gar nicht beherrscht:
Festlegung von Bedingungen für mitzuladene Datensätze beim Eager Loading (Eager Loading Rules)
Unterstützung für E-Tags.
Unterstützung für Nicht-Relationale Datenspeicher („NoSQL“) wie Azure Table Storage und Redis.
Diese Priorisierung stammt aus der Sicht von Microsoft. Der Autor dieses Buchs würde auf Basis seiner Praxiserfahrung einige Punkte anders priorisieren, zum Beispiel die N:M-Abbildung als „kritisch“ hochstufen: Eine Nachbildung von N:M durch zwei 1:N-Beziehungen im Objektmodell ist zwar möglich, macht aber den Programmcode komplexer. Die Migration von bestehenden Entity Framework-Lösungen zu Entity Framework Core wird damit sehr erschwert.
Das gilt auch für die fehlende Unterstützung von Table per Type-Vererbung: Auch hier muss bestehender Programmcode umfangreich geändert werden. Und auch für neue Anwendungen mit einem neuen Datenbankschema und Forward Engineering gibt es ein Problem: Wenn die Vererbung erst mal mit TPH oder TPC realisiert ist, muss man aufwändig die Daten im Datenbankschema umschichten, wenn man später doch auf TPH setzen will.
Außerdem fehlen in Microsofts Listen auch Features wie etwa die Validierung von Entitäten, die unnötige Roundtrips zur Datenbank ersparen kann, wenn schon im RAM klar ist, dass die Entität die erforderlichen Bedingungen nicht erfüllt.
Entity Framework Core kann insbesondere mit folgenden Vorteilen gegenüber dem Vorgänger auftrumpfen:
Entity Framework Core läuft nicht nur in Windows, Linux und MacOS, sondern auch auf Mobilgeräten mit Windows 10, iOS und Android. Auf den Mobilgeräten ist freilich lediglich ein Zugriff auf lokale Datenbanken (z. B. SQLite) vorgesehen.
Entity Framework Core bietet eine höhere Ausführungsgeschwindigkeit – insbesondere beim Datenlesen (dabei wird fast die Leistung wie beim handgeschriebenen Umkopieren von Daten aus einem DataReader-Objekt in ein typisiertes .NET-Objekt erreicht).
Projektionen mit Select() können nun direkt auf Entitätsklassen abgebildet werden. Der Umweg über anonyme .NET-Objekte ist nicht mehr notwendig.
Per „Batching“ fasst Entity Framework Core nun INSERT-, DELETE- und UPDATE-Operationen zu einem Rundgang zum Datenbankmanagementsystem zusammen, statt jeden Befehl einzeln zu senden.
Standardwerte für Spalten in der Datenbank werden nun sowohl beim Reverse Engineering als auch beim Forward Engineering unterstützt.
Zur Schlüsselgenerierung sind neben den klassischen Autowerten nun auch neuere Verfahren wie Sequenzen erlaubt.
Als „Shadow Properties“ bezeichnet Entity Framework Core den jetzt möglichen Zugriff auf Spalten der Datenbanktabelle, für die es kein Attribut in der Klasse gibt.
Angesichts dieser langen Liste von fehlenden Funktionen stellt sich die Frage, ob und wofür Entity Framework Core in der Version 1.x/2.0 überhaupt zu gebrauchen ist.
Das Haupteinsatzgebiet liegt auf den Plattformen, wo Entity Framework bisher gar nicht lief: Windows Phone/Mobile, Android, iOS, Linux und MacOS/X.
Universal Windows Platform (UWP) Apps und Xamarin Apps können nur Entity Framework Core verwenden.
Wenn man eine neue ASP.NET Core-Anwendung entwickeln will und diese nicht auf .NET „Full“ Framework, sondern .NET Core basieren soll, führt kein Weg an Entity Framework Core vorbei, denn das bisherige Entity Framework 6.1.3 läuft nicht auf .NET Core. Allerdings gibtes für ASP.NET Core auch den Weg, als Basis das .NET Framework 4.6.x zu verwenden, sodass man dann auch Entity Framework 6.x nutzen kann.
Für Projekte auf anderen Plattformen gilt:
Eine aufwändige Migration bestehenden Programmcodes werden die verbesserten Features und die höhere Leistung von Entity Framework Core meist nicht rechtfertigen.
Aber in neuen Projekten können Entwickler schon jetzt Entity Framework Core als performante Zukunftstechnik einsetzen und ggf. als Zwischenlösung für Lücken parallel dort noch das bisherige Entity Framework nutzen.
Ein Szenario, in dem der Einsatz von Entity Framework Core auf dem Webserver empfohlen werden kann, ist das Offline-Szenario, bei dem es auf dem Mobilgerät eine lokale Kopie der Serverdatenbank geben soll. In diesem Fall kann man auf dem Client und dem Server mit demselben Datenzugriffscode arbeiten: Der Client verwendet Entity Framework Core für den Zugriff auf SQLite und der Webserver denselben Entity Framework Core-Programmcode für den Zugriff auf einen Microsoft SQL Server (siehe folgende Abbildung).
Bild 2.5Teilen der Datenzugriffsschicht zwischen Mobilgerät und Webserver mit Entity Framework Core
Wenig Sinn macht zum jetzigen Zeitpunkt eine Migration von Entity Framework 6.1.3 auf Entity Framework Core. Dafür sprechen könnte nur die bessere Performance von Entity Framework Core in einigen Fällen. Man muss aber den hohen Umstellungsaufwand im Programmcode beachten.
Für Entity Framework Core gibt es keine Setup.exe. Entity Framework Core installiert man in einem Projekt über Nuget-Pakete.
Entity Framework Core besteht im Gegensatz zum klassischen Entity Framework aus mehreren Nuget-Paketen. Die folgende Tabelle zeigt nur die Wurzelpakete. Deren Abhängigkeiten, zu denen Nuget die zugehörigen Pakete dann automatisch mitinstalliert, sind hier nicht genannt.
Tabelle 3.1 Die wichtigsten auf nuget.org verfügbaren Pakete für Entity Framework Core
Tabelle 3.1 Die wichtigsten auf nuget.org verfügbaren Pakete für Entity Framework Core (Fortsetzung)
In Entity Framework Core Version 2.0 hat Microsoft den Zuschnitt der Pakete abermals geändert. Vorher gab es zu jedem Treiber zwei Pakete, eins davon mit „Design“ im Namen. Die „Design“-Pakete wurden aufgelöst und in die eigentlichen Treiber-Assemblies integriert.
Bild 3.1In Entity Framework Core 2.0 hat Microsoft die Klassen der Microsoft.EntityFrameworkCore.SqlServer.Design.dll in die Microsoft.EntityFrameworkCore.SqlServer.dll integriert.
Die Installation erfolgt mit dem Nuget Package Manager oder dem PowerShell-Commandlet Install-Package in Visual Studio.
Bild 3.2Installation des Treibers für Microsoft SQL Server mit dem Nuget Package Manager-GUI
An der Kommandozeile (Nuget Package Manager Console) installiert man die aktuelle stabile Version mit:
Man installiert die aktuelle Vorab-Version mit:
Man installiert eine bestimmte Version mit:
Bild 3.3Installation von Entity Framework Core 1.1.2 in einer .NET Core 1.1-Konsole
Bild 3.4Bei der Installation von Entity Framework Core 2.0 in einer .NET Core 2.0-Konsole müssen sehr viele Pakete installiert werden.
Bild 3.5Installation des Treibers für Microsoft SQL Server mit dem Nuget Package Manager Console (hier gezeigt in Version 1.1.2)
Alle verfügbaren Versionen eines Pakets kann man an der Nuget Package Manager Console auflisten mit:
Die in den Projekten der aktuellen Projektmappe referenzierten Versionen eines Pakets sieht man mit:
Bild 3.6Das Commandlet Get-Package zeigt, dass einige Projekte bereits auf EF Core 2.0 aktualisiert wurden, andere noch nicht.
Bestehende Projekte aktualisiert man auf eine neue Version von Entity Framework Core mit dem Nuget Package Manager – entweder in seiner grafischen Version oder an der Kommandozeile.
Das Nuget Package Manager-GUI zeigt beim Vorliegen einer neuen Entity Framework Core-Version an, dass zahlreiche Nuget-Pakete zu aktualisieren sind.
Praxistipp 1: Da sich der Nuget Package Manager bei vielen Aktualisierungen manchmal „verheddert“, sollten Sie nicht alle Pakete auf einmal aktualisieren (wie die erste Abbildung es zeigt), sondern nur das eigentliche Wurzelpaket, also das Paket mit dem gewünschten Entity Framework Core-Treiber (siehe zweite Abbildung). Diese Aktualisierung zieht dann auch die Aktualisierung der Abhängigkeiten nach sich.
Bild 3.7Grafische Aktualisierung aller Nuget-Pakete (nicht empfohlen!)
Bild 3.8Besser wählen Sie nur die Wurzelpakete, also das Paket mit dem Datenbanktreiber.
Dies entspricht der Vorgehensweise an der Kommandozeile, auf der man ja man ja auch nicht alle Pakete eintippen möchte, sondern nur das Wurzelpaket aktualisiert, z. B. bei der Aktualisierung auf Entity Framework Core 2.0:
Praxistipp 2: Wenn Sie bei der Aktualisierung von Entity Framework Core 1.x auf Version 2.0 die Fehlermeldung erhalten „Could not install package ‚Microsoft.EntityFrameworkCore.SqlServer 2.0.0‘. You are trying to install this package into a project that targets '.NETFramework,Version=v4.x, but the package does not contain any assembly references or content files that are compatible with that framework.“, kann dies folgende Ursachen haben:
Sie verwenden eine .NET-Version vor 4.6.1, die nicht kompatibel zu .NET Standard 2.0 ist und daher nicht Entity Framework Core 2.0 nutzen kann.
Wenn die Versionsnummer in der Fehlermeldung aber 4.6.1 oder höher ist (vgl. nächste Abbildung), dann liegt dies daran, dass Sie eine zu alte Version von Visual Studio verwenden. Entity Framework Core 2.0 kann erst ab Visual Studio 2015 Update 3 mit installiertem .NET Core eingesetzt werden (auch wenn Sie das klassische .NET Framework nutzen, muss .NET Core auf dem Entwicklungssystem installiert sein!)
Bild 3.9Fehlermeldung beim Aktualisieren auf EF Core 2.0
Praxistipp 3: Bei der Aktualisierung von EF Core 1.x auf Version 2.0 müssen Sie die Referenz auf das Paket „Microsoft.EntityFrameworkCore.SqlServer.Design“ manuell entfernen:
Falls Sie auch eine Referenz auf das Paket „Microsoft.EntityFrameworkCore.Relational.Design“ haben, entfernen Sie auch diese:
Microsoft hat in Entity Framework Core 2.0 den Inhalt der Nuget-Pakete mit „.Design“ am Ende in die gleichnamigen Pakete ohne diesen Zusatz überführt.
Wenn Sie in Ihren Projekten noch Pakete mit Namen „Microsoft.AspNetCore…“ haben, obwohl Sie gar keine ASP.NET Core-basierte Webanwendung schreiben, so können sie auch diese entfernen. Diese Referenzen sind ein Relikt aus den ersten Versionen der Entity Framework Core-Werkzeuge:
Bild 3.10Deinstallation des in Entity Framework Core 2.0 nicht mehr benötigten Pakets Microsoft.EntityFrameworkCore.SqlServer.Design
Praxistipp 4: Manchmal findet Visual Studio nach einer Aktualisierung das Kompilat von anderen Projekten in der gleichen Projektmappe nicht mehr (siehe erste Abbildung). In diesem Fall deaktivieren Sie im Reference Manager (References/Add Reference) das Projekt kurz, um es danach direkt wieder zu wählen (siehe zweite Abbildung).
Bild 3.11Das Projekt ist vorhanden, das Kompilat wird aber nicht gefunden.
Bild 3.12Entfernen und Neu-Einfügen der Referenz
Praxistipp 5: In einer .NET Standard Library kann Entity Framework Core 2.0 nur installiert werden, wenn diese als „Target Framework“ auf „.NET Standard 2.0“ steht. Sonst kommt es zum Fehler: „Package Microsoft.EntityFrameworkCore.SqlServer 2.0.0 is not compatible with netstandard1.6 (.NETStandard,Version=v1.6). Package Microsoft.EntityFrameworkCore.SqlServer 2.0.0 supports: netstandard2.0 (.NETStandard,Version=v2.0)“. Ebenso kann Entity Framework Core 2.0 nicht in einem .NET Core 1.x-Projekt verwendet werden, sondern nur in .NET Core 2.0-Projekten. Die Projekte müssen also ggf. vorher hochgestuft werden (siehe die folgenden Abbildungen).
Bild 3.13Aktualisierung des Target Frameworks auf .NET Standard Version 2.0 in den Projekteigenschaften
Bild 3.14Aktualisierung des Target Frameworks auf .NET Core Version 2.0 in den Projekteigenschaften
Dieses Kapitel erläutert die zentralen Konzepte von Entity Framework Core, getrennt nach den Vorgehensmodellen und den Artefakten von Entity Framework Core.
Entity Framework Core unterstützt sowohl das
ReverseEngineering bestehender Datenbanken (hier wird ein Objektmodell aus einem Datenbankschema erzeugt)
als auch das
ForwardEngineering von Datenbanken aus Objektmodellen heraus (hier wird ein Datenbankschema aus einem Objektmodell erzeugt).
Reverse Engineering (auch oft Database First genannt) bietet sich an, wenn bereits eine Datenbank besteht oder wenn sich die Entwickler entscheiden, die Datenbank auf traditionellem Weg zu erzeugen. Die zweite Option, welche als Forward Engineering bezeichnet wird, gibt dem Entwickler die Möglichkeit, ein Objektmodell zu entwerfen. Aus diesem kann er anschließend ein Datenbankschema generieren.
Für den Entwickler ist meist das Forward Engineering besser, weil man hierbei ein Objektmodell entwerfen kann, wie man es für die Programmierung braucht.
Forward Engineering kann man wahlweise zur Entwicklungszeit (über sogenannte Schemamigrationen) und/oder zur Laufzeit nutzen. Eine Schemamigration ist die Erstellung der Datenbank mit einem intialen Schema oder eine spätere Erweiterung/Änderung des Schemas.
Zur Laufzeit bedeutet, dass die Datenbank erst zur Laufzeit der Anwendung von Entity Framework Core bei Bedarf angelegt (EnsureCreated()) bzw. aktualisiert (Migrate()) wird.
Reverse Engineering findet immer zur Entwicklungszeit statt.
Im Vorgänger, ADO.NET Entity Framework, gab es vier Vorgehensmodelle:
Reverse Engineering mit EDMX-Dateien (alias Database First)
Reverse Engineering mit Code First
Forward Engineering mit EDMX-Dateien (alias Model First)
Forward Engineering mit Code First
Da es in Entity Framework Core kein EDMX mehr gibt, entfallen zwei der Modelle. Das Reverse Engineering und das Forward Engineering in Entity Framework Core sind die Nachfolger der entsprechenden Code First-Vorgehensweisen. Microsoft spricht aber nicht mehr von Code First, weil dieser Name bei vielen Entwicklern Forward Engineering suggeriert. Microsoft spricht allgemein von „Code-based Modelling“.
Bild 4.1Forward Engineering versus Reverse Engineering bei Entity Framework Core
Die folgende Tabelle zeigt einen Vergleich der beiden Vorgehensmodelle.
Tabelle 4.1 Forward Engineering versus Reverse Engineering bei Entity Framework Core
Reverse Engineering
Forward Engineering
Bestehende DB einlesen
✓
Änderungen und Erweiterungen des Datenbankschemas
(Microsoft) ✓ (mit Zusatzwerkzeug Entity Developer)
✓ (Migrationen)
Grafisch modellieren
(Microsoft) ✓ (mit Zusatzwerkzeug Entity Developer)
(Microsoft) ✓ (mit Zusatzwerkzeug Entity Developer)
Stored Procedures
• Manuell aufrufbar (Microsoft) ✓ (mit Zusatzwerkzeug Entity Developer)
• Manuell aufrufbar
Table-valued Functions
• Manuell aufrufbar (Microsoft) ✓ (mit Zusatzwerkzeug Entity Developer)
• Manuell aufrufbar