Schwichtenberg Effizienter Datenzugriff mit Entity Framework Core
1. Auflage 2018
ISBN: 978-3-446-44978-7
Verlag: Carl Hanser
Format: PDF
Kopierschutz: 1 - PDF Watermark
Datenbankprogrammierung mit C# für .NET Framework, .NET Core und Xamarin
E-Book, Deutsch, 468 Seiten
ISBN: 978-3-446-44978-7
Verlag: Carl Hanser
Format: PDF
Kopierschutz: 1 - PDF Watermark
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.
Dr. Holger Schwichtenberg zählt zu Deutschlands bekanntesten Experten für Scripting und professionelle Softwareentwicklung mit Microsoft-Werkzeugen. Im Rahmen des Expertenteams der Firma www.IT-Visions.de schult, berät und unterstützt er Unternehmen jeder Größe. Neben seiner Autorentätigkeit für Fachzeitschriften und heise.de hat er zudem zahlreiche Fachbücher veröffentlicht. Von Microsoft wurde er 20-mal ausgezeichnet als »Most Valuable Professional«.
Autoren/Hrsg.
Fachgebiete
Weitere Infos & Material
1;Inhalt;7
2;Vorwort;17
3;Über den Autor;19
4;1 Einleitung;21
4.1;1.1 Programmiersprache in diesem Buch;21
4.2;1.2 Fallbeispiele in diesem Buch;21
4.2.1;1.2.1 Entitäten;22
4.3;1.3 Anwendungsarten in diesem Buch;25
4.4;1.4 Hilfsroutinen zur Konsolenausgabe;26
4.5;1.5 Programmcodebeispiel zum Download;30
5;2 Was ist Entity Framework Core?;33
5.1;2.1 Was ist ein Objekt-Relationaler Mapper?;33
5.2;2.2 ORM in der .NET-Welt;35
5.3;2.3 Versionsgeschichte von Entity Framework Core;36
5.4;2.4 Unterstützte Betriebssysteme;37
5.5;2.5 Unterstützte .NET-Versionen;37
5.6;2.6 Unterstützte Visual Studio-Versionen;38
5.7;2.7 Unterstützte Datenbanken;39
5.8;2.8 Funktionsumfang von Entity Framework Core;40
5.9;2.9 Funktionen, die dauerhaft entfallen;41
5.10;2.10 Funktionen, die Microsoft bald nachrüsten will;41
5.11;2.11 Hohe Priorität, aber nicht kritisch;42
5.12;2.12 Neue Funktionen in Entity Framework Core;43
5.13;2.13 Einsatzszenarien;44
6;3 Installation von Entity Framework Core;47
6.1;3.1 Nuget-Pakete;47
6.2;3.2 Paketinstallation;50
6.3;3.3 Aktualisierung auf eine neue Version;54
7;4 Konzepte von Entity Framework Core;59
7.1;4.1 Vorgehensmodelle bei Entity Framework Core;59
7.2;4.2 Artefakte bei Entity Framework Core;61
8;5 Reverse Engineering bestehender Datenbanken;63
8.1;5.1 Reverse Engineering mit PowerShell-Befehlen;64
8.2;5.2 Codegenerierung;67
8.3;5.3 .NET Core-Tool;74
8.4;5.4 Schwächen des Reverse Engineering;76
9;6 Forward Engineering für neue Datenbanken;77
9.1;6.1 Regeln für die selbsterstellten Entitätsklassen;79
9.1.1;6.1.1 Properties;79
9.1.2;6.1.2 Datentypen;79
9.1.3;6.1.3 Beziehungen (Master-Detail);79
9.1.4;6.1.4 Vererbung;81
9.1.5;6.1.5 Primärschlüssel;81
9.1.6;6.1.6 Beispiele;81
9.2;6.2 Regeln für die selbsterstellte Kontextklasse;84
9.2.1;6.2.1 Nuget-Pakete;84
9.2.2;6.2.2 Basisklasse;85
9.2.3;6.2.3 Konstruktor;85
9.2.4;6.2.4 Beispiel;85
9.2.5;6.2.5 Provider und Verbindungszeichenfolge;86
9.2.6;6.2.6 Eigene Verbindungen;87
9.2.7;6.2.7 Thread-Sicherheit;87
9.3;6.3 Regeln für die Datenbankschemagenerierung;87
9.4;6.4 Beispiel-Client;88
9.5;6.5 Anpassung per Fluent-API (OnModelCreating());89
9.6;6.6 Das erzeugte Datenmodell;91
10;7 Anpassung des Datenbankschemas;93
10.1;7.1 Persistente versus transiente Klassen;94
10.2;7.2 Namen im Datenbankschema;95
10.3;7.3 Reihenfolge der Spalten in einer Tabelle;95
10.4;7.4 Spaltentypen/Datentypen;96
10.5;7.5 Pflichtfelder und optionale Felder;97
10.6;7.6 Feldlängen;97
10.7;7.7 Primärschlüssel;98
10.8;7.8 Beziehungen und Fremdschlüssel;98
10.9;7.9 Optionale Beziehungen und Pflichtbeziehungen;99
10.10;7.10 Uni- und Bidirektionale Beziehungen;101
10.11;7.11 1:1-Beziehungen;102
10.12;7.12 Indexe festlegen;103
10.13;7.13 Weitere Syntaxoptionen für das Fluent-API;105
10.13.1;7.13.1 Sequentielle Konfiguration;105
10.13.2;7.13.2 Strukturierung durch Statement Lambdas;105
10.13.3;7.13.3 Strukturierung durch Unterroutinen;106
10.13.4;7.13.4 Strukturierung durch Konfigurationsklassen;107
10.14;7.14 Massenkonfiguration mit dem Fluent-API;108
11;8 Datenbankschemamigrationen;111
11.1;8.1 Anlegen der Datenbank zur Laufzeit;111
11.2;8.2 Schemamigrationen zur Entwicklungszeit;112
11.3;8.3 Befehle für die Schemamigrationen;112
11.4;8.4 ef.exe;113
11.5;8.5 Add-Migration;114
11.6;8.6 Update-Database;118
11.7;8.7 Script-Migration;119
11.8;8.8 Weitere Migrationsschritte;119
11.9;8.9 Migrationsszenarien;120
11.10;8.10 Weitere Möglichkeiten;121
11.11;8.11 Schemamigrationen zur Laufzeit;123
12;9 Daten lesen mit LINQ;125
12.1;9.1 Kontextklasse;125
12.2;9.2 LINQ-Abfragen;126
12.3;9.3 Schrittweises Zusammensetzung von LINQ-Abfragen;128
12.4;9.4 Repository-Pattern;129
12.5;9.5 Einsatz von var;130
12.6;9.6 LINQ-Abfragen mit Paging;131
12.7;9.7 Projektionen;133
12.8;9.8 Abfrage nach Einzelobjekten;134
12.9;9.9 Laden anhand des Primärschlüssels mit Find();135
12.10;9.10 LINQ im RAM statt in der Datenbank;135
12.11;9.11 Umgehung für das GroupBy-Problem;139
12.11.1;9.11.1 Mapping auf Nicht-Entitätstypen;139
12.11.2;9.11.2 Entitätsklasse für die Datenbanksicht anlegen;140
12.11.3;9.11.3 Einbinden der Entitätsklasse in die Kontextklasse;140
12.11.4;9.11.4 Verwendung der Pseudo-Entitätsklasse;141
12.11.5;9.11.5 Herausforderung: Migrationen;141
12.11.6;9.11.6 Gruppierungen mit Datenbanksichten;143
12.12;9.12 Kurzübersicht über die LINQ-Syntax;143
12.12.1;9.12.1 Einfache SELECT-Befehle (Alle Datensätze);145
12.12.2;9.12.2 Bedingungen (where);145
12.12.3;9.12.3 Bedingungen mit Mengen (in);146
12.12.4;9.12.4 Sortierungen (orderby);146
12.12.5;9.12.5 Paging (Skip() und Take());147
12.12.6;9.12.6 Projektion;147
12.12.7;9.12.7 Aggregatfunktionen (Count(), Min(), Max(), Average(), Sum());148
12.12.8;9.12.8 Gruppierungen (GroupBy);149
12.12.9;9.12.9 Einzelobjekte (SingleOrDefault(), FirstOrDefault());150
12.12.10;9.12.10 Verbundene Objekte (Include());151
12.12.11;9.12.11 Inner Join (Join);152
12.12.12;9.12.12 Cross Join (Kartesisches Produkt);153
12.12.13;9.12.13 Join mit Gruppierung;153
12.12.14;9.12.14 Unter-Abfragen (Sub-Select);154
13;10 Objektbeziehungen und Ladestrategien;157
13.1;10.1 Standardverhalten;157
13.2;10.2 Kein Lazy Loading;158
13.3;10.3 Eager Loading;160
13.4;10.4 Explizites Nachladen (Explicit Loading);163
13.5;10.5 Preloading mit Relationship Fixup;165
13.6;10.6 Details zum Relationship Fixup;170
14;11 Einfügen, Löschen und Ändern;171
14.1;11.1 Speichern mit SaveChanges();171
14.2;11.2 Änderungsverfolgung auch für Unterobjekte;174
14.3;11.3 Das Foreach-Problem;175
14.4;11.4 Objekte hinzufügen mit Add();176
14.5;11.5 Verbundene Objekte anlegen;178
14.6;11.6 Verbundene Objekte ändern/Relationship Fixup;181
14.7;11.7 Widersprüchliche Beziehungen;184
14.8;11.8 Zusammenfassen von Befehlen (Batching);189
14.9;11.9 Objekte löschen mit Remove();190
14.10;11.10 Löschen mit einem Attrappen-Objekt;191
14.11;11.11 Massenlöschen;192
14.12;11.12 Datenbanktransaktionen;193
14.13;11.13 Change Tracker abfragen;196
14.13.1;11.13.1 Zustand eines Objekts;196
14.13.2;11.13.2 Liste aller geänderten Objekte;198
15;12 Datenänderungskonflikte (Concurrency);201
15.1;12.1 Rückblick;201
15.2;12.2 Im Standard keine Konflikterkennung;202
15.3;12.3 Optimistisches Sperren/ Konflikterkennung;204
15.4;12.4 Konflikterkennung für alle Eigenschaften;205
15.5;12.5 Konflikteinstellung per Konvention;206
15.6;12.6 Fallweise Konflikteinstellung;207
15.7;12.7 Zeitstempel (Timestamp);208
15.8;12.8 Konflikte auflösen;210
15.9;12.9 Pessimistisches Sperren bei Entity Framework Core;214
16;13 Protokollierung (Logging);219
16.1;13.1 Verwendung der Erweiterungsmethode Log();219
16.2;13.2 Implementierung der Log()-Erweiterungsmethode;221
16.3;13.3 Protokollierungskategorien;224
17;14 Asynchrone Programmierung;225
17.1;14.1 Asynchrone Erweiterungsmethoden;225
17.2;14.2 ToListAsync();225
17.3;14.3 SaveChangesAsync();227
17.4;14.4 ForeachAsync();228
18;15 Dynamische LINQ-Abfragen;231
18.1;15.1 Schrittweises Zusammensetzen von LINQ-Abfragen;231
18.2;15.2 Expression Trees;233
18.3;15.3 Dynamic LINQ;236
19;16 Daten lesen und ändern mit SQL, Stored Procedures und Table Valued Functions;239
19.1;16.1 Abfragen mit FromSql();239
19.2;16.2 Zusammensetzbarkeit von LINQ und SQL;241
19.3;16.3 Globale Abfragefilter bei SQL-Abfragen (ab Version 2.0);243
19.4;16.4 Stored Procedures und Table Valued Functions;244
19.5;16.5 Globale Abfragefilter bei Stored Procedures und Table Valued Functions;245
19.6;16.6 Nicht-Entitätsklassen als Ergebnismenge;246
19.7;16.7 SQL-DML-Befehle ohne Resultset;248
20;17 Weitere Tipps und Tricks zum Mapping;249
20.1;17.1 Shadow Properties;249
20.1.1;17.1.1 Automatische Shadow Properties;249
20.1.2;17.1.2 Festlegung eines Shadow Property;250
20.1.3;17.1.3 Ausgabe aller Shadow Properties einer Entitätsklasse;250
20.1.4;17.1.4 Lesen und Ändern eines Shadow Property;251
20.1.5;17.1.5 LINQ-Abfragen mit Shadow Properties;252
20.1.6;17.1.6 Praxisbeispiel: Automatisches Setzen des Shadow Property bei jedem Speichern;252
20.2;17.2 Tabellenaufteilung (Table Splitting);253
20.3;17.3 Berechnete Spalten (Computed Columns);256
20.3.1;17.3.1 Automatisches SELECT;257
20.3.2;17.3.2 Praxistipp: Spalten mit einer Berechnungsformel anlegen;257
20.3.3;17.3.3 Spalten mit einer Berechnungsformel nutzen;259
20.3.4;17.3.4 Spalten mit einer Berechnungsformel beim Reverse Engineering;261
20.4;17.4 Standardwerte (Default Values);262
20.4.1;17.4.1 Standardwerte beim Forward Engineering festlegen;262
20.4.2;17.4.2 Standardwerte verwenden;263
20.4.3;17.4.3 Praxistipp: Standardwerte schon beim Anlegen des Objekts vergeben;265
20.4.4;17.4.4 Standardwerte beim Reverse Engineering;266
20.5;17.5 Sequenzobjekte (Sequences);267
20.5.1;17.5.1 Erstellen von Sequenzen beim Forward Engineering;267
20.5.2;17.5.2 Sequenzen im Einsatz;268
20.6;17.6 Alternative Schlüssel;271
20.6.1;17.6.1 Alternative Schlüssel definieren;272
20.6.2;17.6.2 Alternative Schlüssel im Einsatz;274
20.7;17.7 Kaskadierendes Löschen (Cascading Delete);275
20.8;17.8 Abbildung von Datenbanksichten (Views);278
20.8.1;17.8.1 Datenbanksicht anlegen;279
20.8.2;17.8.2 Entitätsklasse für die Datenbanksicht anlegen;279
20.8.3;17.8.3 Einbinden der Entitätsklasse in die Kontextklasse;279
20.8.4;17.8.4 Verwendung der Datenbanksicht;280
20.8.5;17.8.5 Herausforderung: Migrationen;280
21;18 Weitere Tipps und Tricks zu LINQ;283
21.1;18.1 Globale Abfragefilter (ab Version 2.0);283
21.1.1;18.1.1 Filter definieren;283
21.1.2;18.1.2 Filter nutzen;284
21.1.3;18.1.3 Praxistipp: Filter ignorieren;285
21.2;18.2 Zukünftige Abfragen (Future Queries);285
22;19 Leistungsoptimierung (Performance Tuning);287
22.1;19.1 Vorgehensmodell zur Leistungsoptimierung bei Entity Framework Core;287
22.2;19.2 Best Practices für Ihre eigenen Leistungstests;288
22.3;19.3 Leistungsvergleich verschiedener Dattenzugriffstechniken in .NET;288
22.4;19.4 Objektzuweisung optimieren;290
22.5;19.5 Massenoperationen;292
22.5.1;19.5.1 Einzellöschen;292
22.5.2;19.5.2 Optimierung durch Batching;293
22.5.3;19.5.3 Löschen ohne Laden mit Pseudo-Objekten;294
22.5.4;19.5.4 Einsatz von klassischem SQL anstelle des Entity Framework Core-APIs;295
22.5.5;19.5.5 Lamdba-Ausdrücke für Massenlöschen mit EFPlus;297
22.5.6;19.5.6 Massenaktualisierung mit EFPlus;298
22.6;19.6 Leistungsoptimierung durch No-Tracking;299
22.6.1;19.6.1 No-Tracking aktivieren;300
22.6.2;19.6.2 No-Tracking fast immer möglich;302
22.6.3;19.6.3 No-Tracking im änderbaren Datagrid;305
22.6.4;19.6.4 QueryTrackingBehavior und AsTracking();306
22.6.5;19.6.5 Best Practices;308
22.7;19.7 Auswahl der besten Ladestrategie;308
22.8;19.8 Zwischenspeicherung (Caching);309
22.8.1;19.8.1 MemoryCache;309
22.8.2;19.8.2 Abstraktion CacheManager;312
22.9;19.9 Second-Level-Caching mit EFPlus;316
22.9.1;19.9.1 Einrichten des Second-Level-Cache;317
22.9.2;19.9.2 Verwenden des Second-Level-Cache;317
23;20 Softwarearchitektur mit Entity Framework Core;321
23.1;20.1 Monolithisches Modell;321
23.2;20.2 Entity Framework Core als Datenzugriffsschicht;322
23.3;20.3 Reine Geschäftslogik;324
23.4;20.4 Geschäftsobjekt- und ViewModel-Klassen;325
23.5;20.5 Verteilte Systeme;326
23.6;20.6 Fazit;329
24;21 Zusatzwerkzeuge;331
24.1;21.1 Entity Framework Core Power Tools;331
24.1.1;21.1.1 Funktionsüberblick;331
24.1.2;21.1.2 Reverse Engineering mit Entity Framework Core Power Tools;332
24.1.3;21.1.3 Diagramme mit Entity Framework Core Power Tools;336
24.2;21.2 LINQPad;337
24.2.1;21.2.1 Aufbau von LINQPad;338
24.2.2;21.2.2 Datenquellen einbinden;339
24.2.3;21.2.3 LINQ-Befehle ausführen;342
24.2.4;21.2.4 Speichern;345
24.2.5;21.2.5 Weitere LINQPad-Treiber;345
24.2.6;21.2.6 Interaktive Programmcodeeingabe;346
24.2.7;21.2.7 Fazit zu LINQPad;347
24.3;21.3 Entity Developer;347
24.3.1;21.3.1 Reverse Engineering mit Entity Developer;348
24.3.2;21.3.2 Forward Engineering mit Entity Developer;359
24.4;21.4 Entity Framework Profiler;364
24.4.1;21.4.1 Einbinden des Entity Framework Profilers;366
24.4.2;21.4.2 Befehle überwachen mit Entity Framework Profiler;366
24.4.3;21.4.3 Warnungen vor potenziellen Problemen;369
24.4.4;21.4.4 Analysefunktionen;369
24.4.5;21.4.5 Fazit zu Entity Framework Profiler;370
25;22 Zusatzkomponenten;371
25.1;22.1 Entity Framework Plus (EFPlus);371
25.2;22.2 Second-Level-Caching mit EFSecondLevelCache.Core;372
25.3;22.3 Objekt-Objekt-Mapping und AutoMapper;372
25.3.1;22.3.1 Objekt-Objekt-Mapping per Reflection;374
25.3.2;22.3.2 AutoMapper;377
25.3.3;22.3.3 Beispiel;378
25.3.4;22.3.4 Abbildungen konfigurieren;379
25.3.5;22.3.5 Abbildung ausführen mit Map();380
25.3.6;22.3.6 Abbildungskonventionen;381
25.3.7;22.3.7 Profilklassen;383
25.3.8;22.3.8 Verbundene Objekte;383
25.3.9;22.3.9 Manuelle Abbildungen;384
25.3.10;22.3.10 Typkonvertierungen;386
25.3.11;22.3.11 Objektmengen;388
25.3.12;22.3.12 Vererbung;389
25.3.13;22.3.13 Generische Klassen;391
25.3.14;22.3.14 Zusatzaktionen vor und nach dem Mapping;394
25.3.15;22.3.15 Geschwindigkeit;395
25.3.16;22.3.16 Fazit zu AutoMapper;396
26;23 Praxislösungen;399
26.1;23.1 Entity Framework Core in einer ASP.NET Core-Anwendung;399
26.1.1;23.1.1 Das Fallbeispiel “MiracleList“ 379;14
26.1.2;23.1.2 Architektur;403
26.1.3;23.1.3 Entitätsklassen;405
26.1.4;23.1.4 Entity Framework Core-Kontextklasse;407
26.1.5;23.1.5 Lebensdauer der Kontextklasse in ASP.NET Core-Anwendungen;409
26.1.6;23.1.6 Geschäftslogik;410
26.1.7;23.1.7 WebAPI;418
26.1.8;23.1.8 Verwendung von Entity Framework Core per Dependency Injection;428
26.1.9;23.1.9 Praxistipp: Kontextinstanzpooling (DbContext Pooling);431
26.2;23.2 Entity Framework Core in einer Universal Windows Platform App;432
26.2.1;23.2.1 Das Fallbeispiel “MiracleList Light“ 412;15
26.2.2;23.2.2 Architektur;433
26.2.3;23.2.3 Entitätsklassen;435
26.2.4;23.2.4 Entity Framework Core-Kontextklasse;436
26.2.5;23.2.5 Startcode;436
26.2.6;23.2.6 Erzeugte Datenbank;437
26.2.7;23.2.7 Datenzugriffscode;439
26.2.8;23.2.8 Benutzeroberfläche;443
26.3;23.3 Entity Framework Core in einer Xamarin-Cross-Platform-App;444
26.3.1;23.3.1 Das Fallbeispiel “MiracleList Light“ 424;15
26.3.2;23.3.2 Architektur;446
26.3.3;23.3.3 Entitätsklassen;448
26.3.4;23.3.4 Entity Framework Core-Kontextklasse;448
26.3.5;23.3.5 Startcode;450
26.3.6;23.3.6 Erzeugte Datenbank;450
26.3.7;23.3.7 Datenzugriffscode;450
26.3.8;23.3.8 Benutzeroberfläche;454
26.4;23.4 N:M-Beziehungen zu sich selbst;455
27;24 Quellen im Internet;461
28;Index;463
29;Leere Seite;2
1 | Einleitung |
1.1 | Programmiersprache in diesem Buch |
Als Programmiersprache kommt in diesem Buch C# zum Einsatz, weil dies die bei weitem am häufigsten verwendete Programmiersprache in .NET ist. Der Autor dieses Buchs programmiert in einigen Kundenprojekten .NET-Anwendungen zwar auch in Visual Basic .NET, leider bietet dieses Buch jedoch nicht den Raum, alle Listings in beiden Sprachen wiederzugeben.
Eine Sprachkonvertierung zwischen C# und Visual Basic .NET ist im WWW kostenfrei verfügbar auf der Website http://converter.telerik.com.
1.2 | Fallbeispiele in diesem Buch |
Die meisten Beispielprogrammcodes in diesem Buch drehen sich um das Fallbeispiel der fiktiven Fluggesellschaft „World Wide Wings“, abgekürzt WWWings (siehe auch www.world-wide-wings.de).
Bild 1.1 Logo der fiktiven Fluggesellschaft „World Wide Wings“
HINWEIS: In einzeln Unterkapitel werden andere Fallbeispiele verwendet (z.?B. die Aufgabenverwaltung „MiracleList“). Diese Fallbeispiele werden dann in den jeweiligen Kapiteln erläutert.
1.2.1 | Entitäten |
Im Anwendungsfall „World Wide Wings“ geht es um folgende Entitäten:
-
Flüge zwischen zwei Orten, bei denen die Orte bewusst nicht als eigene Entität modelliert wurden, sondern Zeichenketten sind (dies vereinfacht das Verständnis vieler Beispiele)
-
Passagiere, die auf Flügen fliegen
-
Mitarbeiter der Fluggesellschaft, die wiederum Vorgesetzte haben, die auch Mitarbeiter sind
-
Piloten als eine Spezialisierung von Mitarbeitern
-
Personen als Sammlung der gemeinsamen Eigenschaften für alle Menschen in diesem Beispiel. Personen gibt es aber nicht eigenständig, sondern nur in den Ausprägungen/Spezialisierungen Passagier, Mitarbeiter und Pilot. Im objektorientierten Sinne ist Person also eine abstrakte Basisklasse, die keine Instanzen besitzen kann, sondern nur der Vererbung dient.
Es gibt zwei Datenmodelle:
-
Das etwas einfachere Modell #1 ist das Ergebnis klassischen relationalen Datenbankdesigns mit Normalisierung. Das Objektmodell daraus entsteht per Reverse Engineering.
-
Modell #2 ist das Ergebnis des Forward Engineering mit Entity Framework Core aus einem Objektmodell. Zusätzlich gibt es hier weitere Entitäten (Persondetail, Flugzeugtyp und Flugzeugtypdetail), um weitere Modellierungsaspekte aufzeigen zu können.
In Modell #1 gibt es eine jeweils eigene Tabelle für Personen (auch wenn es keine eigenständigen Personen gibt), Mitarbeiter, Piloten und Passagiere. Diese Aufteilung entspricht den Klassen im Objektmodell.
In Modell #2 gibt es lediglich die Tabellen Passagiere und Mitarbeiter für diese vier Entitäten. Entity Framework Core ist derzeit etwas eingeschränkt und unterstützt das Konzept Table per Type (also eine eigenständige Tabelle für jede Klasse) nicht. Daher umfasst die Tabelle Passagiere auch alle Eigenschaften von Person. Die Tabelle Mitarbeiter umfasst neben den Personeneigenschaften die Eigenschaften der Entitäten Mitarbeiter und Pilot. In der Tabelle wird per Diskriminatorspalte unterschieden zwischen Datensätzen, die ein Mitarbeiter sind, und solchen, die ein Pilot sind. Entity Framework Core mischt hier die Konzepte Table per Concrete Type (TPC) und Table per Hierarchy (TPH). Einen dezidierten Einfluss auf diese Abbildung hat man in Entity Framework Core 1.x/2.0 noch nicht. Das klassische Entity Framework bietet hier mehr Optionen.
Abhängigkeitsarten sind hier:
-
Ein Flug muss einen Piloten besitzen. Der Copilot ist optional.
-
Ein Flug kann optional einen Flugzeutyp zugeordnet haben.
-
Jede Person und damit auch jeder Pilot und Passagier muss ein Persondetail-Objekt besitzen.
In diesem Buch kommen beide Datenmodelle vor, teilweise auch in modifizierter Form, um bestimmte Szenarien (z.?B. Datenbankschemamigrationen) aufzuzeigen.
Bitte beachten Sie, dass die Objektmodelle, die in diesem Buch zu den Datenmodellen erstellt werden, nicht das Idealbild eines Objektmodells darstellen können, denn Entity Framework Core unterstützt einige Mapping-Möglichkeiten wie z.?B. das N:M-Mapping noch nicht. Das Objektmodell zum einfachen Datenmodell ist das automatisch von Entity Framework Core aus der Datenbank generierte Objektmodell (Reverse Engineering); es ist bewusst nicht verändert worden.
Bild 1.2 World Wide Wings-Datenmodell in der einfacheren Version
Bild 1.3 Objektmodell zum World Wide Wings-Datenmodell in der einfacheren Version
Bild 1.4 World Wide Wings-Datenmodell in der komplexeren Version
Bild 1.5 Objektmodell zum World Wide Wings-Datenmodell in der komplexeren Version
1.3 | Anwendungsarten in diesem Buch |
In diesem Buch erfolgen Bildschirmausgaben meist an der textbasierten Konsole in Konsolenanwendungen, denn dies ermöglicht die Fokussierung auf den Datenbankzugriff. Beim Einsatz von grafischen Benutzeroberflächen wie WPF, Windows Forms, ASP.NET Webforms oder ASP.NET MVC ist die Darstellung durch Datenbindung entkoppelt, das heißt man würde immer ein zweites Listing brauchen, um zu verstehen, dass die Datenzugriffe überhaupt liefern. Eingaben des Benutzers werden in den Konsolenbeispielen durch Variablen zu Beginn des Programmcodes simuliert.
Der Autor dieses Buchs führt seit vielen Jahren Schulungen und Beratungseinsätze im Bereich Datenzugriff durch und hat dabei die Erfahrung gemacht, dass Konsolenausgaben das didaktisch beste Instrument sind, da die Listings sonst sehr umfangreich und damit schlechter zu verstehen sind.
Natürlich ist die Konsolenausgabe in 99?% der Fälle der Softwareentwicklung nicht die gängige Praxis. Grafische Benutzeroberflächen sind Inhalt anderer Bücher, und die Datenbindung hat in der Regel keinen Einfluss auf die Form des Datenzugriffs. Dort, wo der Datenzugriff doch relevant ist, wird dieses Buch auch Datenbindungsbeispiele zeigen.
1.4 | Hilfsroutinen zur Konsolenausgabe |
Für die Bildschirmausgabe an der Konsole wird an mehreren Stellen nicht nur Console.WriteLine() verwendet, sondern auch Hilfsroutinen kommen zur Anwendung, die farbige Bildschirmausgaben erzeugen. Diese Hilfsroutinen in der Klasse aus der ITV_DemoUtil.dll sind hier zum besseren Verständnis abgedruckt:
Listing 1.1 Klasse CUI mit Hilfsroutinen für die Bildschirmausgabe an der Konsole
using System; using System.Runtime.InteropServices; using System.Web; using ITVisions.UI; using System.Diagnostics; namespace ITVisions { /// public static class CUI { public static bool IsDebug = false; public static bool IsVerbose = false; #region Ausgaben unter bestimmten Bedingungen ///...