Effizienter Datenzugriff mit Entity Framework Core - Datenbankprogrammierung mit C# für .NET Framework, .NET Core und Xamarin

Holger Schwichtenberg

Effizienter Datenzugriff mit Entity Framework Core

Datenbankprogrammierung mit C# für .NET Framework, .NET Core und Xamarin

2018

468 Seiten

Format: PDF, ePUB, Online Lesen

E-Book: €  41,99

E-Book kaufen

E-Book kaufen

ISBN: 9783446449787

 

Inhalt

7

Vorwort

17

Über den Autor

19

1 Einleitung

21

1.1 Programmiersprache in diesem Buch

21

1.2 Fallbeispiele in diesem Buch

21

1.2.1 Entitäten

22

1.3 Anwendungsarten in diesem Buch

25

1.4 Hilfsroutinen zur Konsolenausgabe

26

1.5 Programmcodebeispiel zum Download

30

2 Was ist Entity Framework Core?

33

2.1 Was ist ein Objekt-Relationaler Mapper?

33

2.2 ORM in der .NET-Welt

35

2.3 Versionsgeschichte von Entity Framework Core

36

2.4 Unterstützte Betriebssysteme

37

2.5 Unterstützte .NET-Versionen

37

2.6 Unterstützte Visual Studio-Versionen

38

2.7 Unterstützte Datenbanken

39

2.8 Funktionsumfang von Entity Framework Core

40

2.9 Funktionen, die dauerhaft entfallen

41

2.10 Funktionen, die Microsoft bald nachrüsten will

41

2.11 Hohe Priorität, aber nicht kritisch

42

2.12 Neue Funktionen in Entity Framework Core

43

2.13 Einsatzszenarien

44

3 Installation von Entity Framework Core

47

3.1 Nuget-Pakete

47

3.2 Paketinstallation

50

3.3 Aktualisierung auf eine neue Version

54

4 Konzepte von Entity Framework Core

59

4.1 Vorgehensmodelle bei Entity Framework Core

59

4.2 Artefakte bei Entity Framework Core

61

5 Reverse Engineering bestehender Datenbanken

63

5.1 Reverse Engineering mit PowerShell-Befehlen

64

5.2 Codegenerierung

67

5.3 .NET Core-Tool

74

5.4 Schwächen des Reverse Engineering

76

6 Forward Engineering für neue Datenbanken

77

6.1 Regeln für die selbsterstellten Entitätsklassen

79

6.1.1 Properties

79

6.1.2 Datentypen

79

6.1.3 Beziehungen (Master-Detail)

79

6.1.4 Vererbung

81

6.1.5 Primärschlüssel

81

6.1.6 Beispiele

81

6.2 Regeln für die selbsterstellte Kontextklasse

84

6.2.1 Nuget-Pakete

84

6.2.2 Basisklasse

85

6.2.3 Konstruktor

85

6.2.4 Beispiel

85

6.2.5 Provider und Verbindungszeichenfolge

86

6.2.6 Eigene Verbindungen

87

6.2.7 Thread-Sicherheit

87

6.3 Regeln für die Datenbankschemagenerierung

87

6.4 Beispiel-Client

88

6.5 Anpassung per Fluent-API (OnModelCreating())

89

6.6 Das erzeugte Datenmodell

91

7 Anpassung des Datenbankschemas

93

7.1 Persistente versus transiente Klassen

94

7.2 Namen im Datenbankschema

95

7.3 Reihenfolge der Spalten in einer Tabelle

95

7.4 Spaltentypen/Datentypen

96

7.5 Pflichtfelder und optionale Felder

97

7.6 Feldlängen

97

7.7 Primärschlüssel

98

7.8 Beziehungen und Fremdschlüssel

98

7.9 Optionale Beziehungen und Pflichtbeziehungen

99

7.10 Uni- und Bidirektionale Beziehungen

101

7.11 1:1-Beziehungen

102

7.12 Indexe festlegen

103

7.13 Weitere Syntaxoptionen für das Fluent-API

105

7.13.1 Sequentielle Konfiguration

105

7.13.2 Strukturierung durch Statement Lambdas

105

7.13.3 Strukturierung durch Unterroutinen

106

7.13.4 Strukturierung durch Konfigurationsklassen

107

7.14 Massenkonfiguration mit dem Fluent-API

108

8 Datenbankschemamigrationen

111

8.1 Anlegen der Datenbank zur Laufzeit

111

8.2 Schemamigrationen zur Entwicklungszeit

112

8.3 Befehle für die Schemamigrationen

112

8.4 ef.exe

113

8.5 Add-Migration

114

8.6 Update-Database

118

8.7 Script-Migration

119

8.8 Weitere Migrationsschritte

119

8.9 Migrationsszenarien

120

8.10 Weitere Möglichkeiten

121

8.11 Schemamigrationen zur Laufzeit

123

9 Daten lesen mit LINQ

125

9.1 Kontextklasse

125

9.2 LINQ-Abfragen

126

9.3 Schrittweises Zusammensetzung von LINQ-Abfragen

128

9.4 Repository-Pattern

129

9.5 Einsatz von var

130

9.6 LINQ-Abfragen mit Paging

131

9.7 Projektionen

133

9.8 Abfrage nach Einzelobjekten

134

9.9 Laden anhand des Primärschlüssels mit Find()

135

9.10 LINQ im RAM statt in der Datenbank

135

9.11 Umgehung für das GroupBy-Problem

139

9.11.1 Mapping auf Nicht-Entitätstypen

139

9.11.2 Entitätsklasse für die Datenbanksicht anlegen

140

9.11.3 Einbinden der Entitätsklasse in die Kontextklasse

140

9.11.4 Verwendung der Pseudo-Entitätsklasse

141

9.11.5 Herausforderung: Migrationen

141

9.11.6 Gruppierungen mit Datenbanksichten

143

9.12 Kurzübersicht über die LINQ-Syntax

143

9.12.1 Einfache SELECT-Befehle (Alle Datensätze)

145

9.12.2 Bedingungen (where)

145

9.12.3 Bedingungen mit Mengen (in)

146

9.12.4 Sortierungen (orderby)

146

9.12.5 Paging (Skip() und Take())

147

9.12.6 Projektion

147

9.12.7 Aggregatfunktionen (Count(), Min(), Max(), Average(), Sum())

148

9.12.8 Gruppierungen (GroupBy)

149

9.12.9 Einzelobjekte (SingleOrDefault(), FirstOrDefault())

150

9.12.10 Verbundene Objekte (Include())

151

9.12.11 Inner Join (Join)

152

9.12.12 Cross Join (Kartesisches Produkt)

153

9.12.13 Join mit Gruppierung

153

9.12.14 Unter-Abfragen (Sub-Select)

154

10 Objektbeziehungen und Ladestrategien

157

10.1 Standardverhalten

157

10.2 Kein Lazy Loading

158

10.3 Eager Loading

160

10.4 Explizites Nachladen (Explicit Loading)

163

10.5 Preloading mit Relationship Fixup

165

10.6 Details zum Relationship Fixup

170

11 Einfügen, Löschen und Ändern

171

11.1 Speichern mit SaveChanges()

171

11.2 Änderungsverfolgung auch für Unterobjekte

174

11.3 Das Foreach-Problem

175

11.4 Objekte hinzufügen mit Add()

176

11.5 Verbundene Objekte anlegen

178

11.6 Verbundene Objekte ändern/Relationship Fixup

181

11.7 Widersprüchliche Beziehungen

184

11.8 Zusammenfassen von Befehlen (Batching)

189

11.9 Objekte löschen mit Remove()

190

11.10 Löschen mit einem Attrappen-Objekt

191

11.11 Massenlöschen

192

11.12 Datenbanktransaktionen

193

11.13 Change Tracker abfragen

196

11.13.1 Zustand eines Objekts

196

11.13.2 Liste aller geänderten Objekte

198

12 Datenänderungskonflikte (Concurrency)

201

12.1 Rückblick

201

12.2 Im Standard keine Konflikterkennung

202

12.3 Optimistisches Sperren/ Konflikterkennung

204

12.4 Konflikterkennung für alle Eigenschaften

205

12.5 Konflikteinstellung per Konvention

206

12.6 Fallweise Konflikteinstellung

207

12.7 Zeitstempel (Timestamp)

208

12.8 Konflikte auflösen

210

12.9 Pessimistisches Sperren bei Entity Framework Core

214

13 Protokollierung (Logging)

219

13.1 Verwendung der Erweiterungsmethode Log()

219

13.2 Implementierung der Log()-Erweiterungsmethode

221

13.3 Protokollierungskategorien

224

14 Asynchrone Programmierung

225

14.1 Asynchrone Erweiterungsmethoden

225

14.2 ToListAsync()

225

14.3 SaveChangesAsync()

227

14.4 ForeachAsync()

228

15 Dynamische LINQ-Abfragen

231

15.1 Schrittweises Zusammensetzen von LINQ-Abfragen

231

15.2 Expression Trees

233

15.3 Dynamic LINQ

236

16 Daten lesen und ändern mit SQL, Stored Procedures und Table Valued Functions

239

16.1 Abfragen mit FromSql()

239

16.2 Zusammensetzbarkeit von LINQ und SQL

241

16.3 Globale Abfragefilter bei SQL-Abfragen (ab Version 2.0)

243

16.4 Stored Procedures und Table Valued Functions

244

16.5 Globale Abfragefilter bei Stored Procedures und Table Valued Functions

245

16.6 Nicht-Entitätsklassen als Ergebnismenge

246

16.7 SQL-DML-Befehle ohne Resultset

248

17 Weitere Tipps und Tricks zum Mapping

249

17.1 Shadow Properties

249

17.1.1 Automatische Shadow Properties

249

17.1.2 Festlegung eines Shadow Property

250

17.1.3 Ausgabe aller Shadow Properties einer Entitätsklasse

250

17.1.4 Lesen und Ändern eines Shadow Property

251

17.1.5 LINQ-Abfragen mit Shadow Properties

252

17.1.6 Praxisbeispiel: Automatisches Setzen des Shadow Property bei jedem Speichern

252

17.2 Tabellenaufteilung (Table Splitting)

253

17.3 Berechnete Spalten (Computed Columns)

256

17.3.1 Automatisches SELECT

257

17.3.2 Praxistipp: Spalten mit einer Berechnungsformel anlegen

257

17.3.3 Spalten mit einer Berechnungsformel nutzen

259

17.3.4 Spalten mit einer Berechnungsformel beim Reverse Engineering

261

17.4 Standardwerte (Default Values)

262

17.4.1 Standardwerte beim Forward Engineering festlegen

262

17.4.2 Standardwerte verwenden

263

17.4.3 Praxistipp: Standardwerte schon beim Anlegen des Objekts vergeben

265

17.4.4 Standardwerte beim Reverse Engineering

266

17.5 Sequenzobjekte (Sequences)

267

17.5.1 Erstellen von Sequenzen beim Forward Engineering

267

17.5.2 Sequenzen im Einsatz

268

17.6 Alternative Schlüssel

271

17.6.1 Alternative Schlüssel definieren

272

17.6.2 Alternative Schlüssel im Einsatz

274

17.7 Kaskadierendes Löschen (Cascading Delete)

275

17.8 Abbildung von Datenbanksichten (Views)

278

17.8.1 Datenbanksicht anlegen

279

17.8.2 Entitätsklasse für die Datenbanksicht anlegen

279

17.8.3 Einbinden der Entitätsklasse in die Kontextklasse

279

17.8.4 Verwendung der Datenbanksicht

280

17.8.5 Herausforderung: Migrationen

280

18 Weitere Tipps und Tricks zu LINQ

283

18.1 Globale Abfragefilter (ab Version 2.0)

283

18.1.1 Filter definieren

283

18.1.2 Filter nutzen

284

18.1.3 Praxistipp: Filter ignorieren

285

18.2 Zukünftige Abfragen (Future Queries)

285

19 Leistungsoptimierung (Performance Tuning)

287

19.1 Vorgehensmodell zur Leistungsoptimierung bei Entity Framework Core

287

19.2 Best Practices für Ihre eigenen Leistungstests

288

19.3 Leistungsvergleich verschiedener Dattenzugriffstechniken in .NET

288

19.4 Objektzuweisung optimieren

290

19.5 Massenoperationen

292

19.5.1 Einzellöschen

292

19.5.2 Optimierung durch Batching

293

19.5.3 Löschen ohne Laden mit Pseudo-Objekten

294

19.5.4 Einsatz von klassischem SQL anstelle des Entity Framework Core-APIs

295

19.5.5 Lamdba-Ausdrücke für Massenlöschen mit EFPlus

297

19.5.6 Massenaktualisierung mit EFPlus

298

19.6 Leistungsoptimierung durch No-Tracking

299

19.6.1 No-Tracking aktivieren

300

19.6.2 No-Tracking fast immer möglich

302

19.6.3 No-Tracking im änderbaren Datagrid

305

19.6.4 QueryTrackingBehavior und AsTracking()

306

19.6.5 Best Practices

308

19.7 Auswahl der besten Ladestrategie

308

19.8 Zwischenspeicherung (Caching)

309

19.8.1 MemoryCache

309

19.8.2 Abstraktion CacheManager

312

19.9 Second-Level-Caching mit EFPlus

316

19.9.1 Einrichten des Second-Level-Cache

317

19.9.2 Verwenden des Second-Level-Cache

317

20 Softwarearchitektur mit Entity Framework Core

321

20.1 Monolithisches Modell

321

20.2 Entity Framework Core als Datenzugriffsschicht

322

20.3 Reine Geschäftslogik

324

20.4 Geschäftsobjekt- und ViewModel-Klassen

325

20.5 Verteilte Systeme

326

20.6 Fazit

329

21 Zusatzwerkzeuge

331

21.1 Entity Framework Core Power Tools

331

21.1.1 Funktionsüberblick

331

21.1.2 Reverse Engineering mit Entity Framework Core Power Tools

332

21.1.3 Diagramme mit Entity Framework Core Power Tools

336

21.2 LINQPad

337

21.2.1 Aufbau von LINQPad

338

21.2.2 Datenquellen einbinden

339

21.2.3 LINQ-Befehle ausführen

342

21.2.4 Speichern

345

21.2.5 Weitere LINQPad-Treiber

345

21.2.6 Interaktive Programmcodeeingabe

346

21.2.7 Fazit zu LINQPad

347

21.3 Entity Developer

347

21.3.1 Reverse Engineering mit Entity Developer

348

21.3.2 Forward Engineering mit Entity Developer

359

21.4 Entity Framework Profiler

364

21.4.1 Einbinden des Entity Framework Profilers

366

21.4.2 Befehle überwachen mit Entity Framework Profiler

366

21.4.3 Warnungen vor potenziellen Problemen

369

21.4.4 Analysefunktionen

369

21.4.5 Fazit zu Entity Framework Profiler

370

22 Zusatzkomponenten

371

22.1 Entity Framework Plus (EFPlus)

371

22.2 Second-Level-Caching mit EFSecondLevelCache.Core

372

22.3 Objekt-Objekt-Mapping und AutoMapper

372

22.3.1 Objekt-Objekt-Mapping per Reflection

374

22.3.2 AutoMapper

377

22.3.3 Beispiel

378

22.3.4 Abbildungen konfigurieren

379

22.3.5 Abbildung ausführen mit Map()

380

22.3.6 Abbildungskonventionen

381

22.3.7 Profilklassen

383

22.3.8 Verbundene Objekte

383

22.3.9 Manuelle Abbildungen

384

22.3.10 Typkonvertierungen

386

22.3.11 Objektmengen

388

22.3.12 Vererbung

389

22.3.13 Generische Klassen

391

22.3.14 Zusatzaktionen vor und nach dem Mapping

394

22.3.15 Geschwindigkeit

395

22.3.16 Fazit zu AutoMapper

396

23 Praxislösungen

399

23.1 Entity Framework Core in einer ASP.NET Core-Anwendung

399

23.1.1 Das Fallbeispiel “MiracleList“ 379

14

23.1.2 Architektur

403

23.1.3 Entitätsklassen

405

23.1.4 Entity Framework Core-Kontextklasse

407

23.1.5 Lebensdauer der Kontextklasse in ASP.NET Core-Anwendungen

409

23.1.6 Geschäftslogik

410

23.1.7 WebAPI

418

23.1.8 Verwendung von Entity Framework Core per Dependency Injection

428

23.1.9 Praxistipp: Kontextinstanzpooling (DbContext Pooling)

431

23.2 Entity Framework Core in einer Universal Windows Platform App

432

23.2.1 Das Fallbeispiel “MiracleList Light“ 412

15

23.2.2 Architektur

433

23.2.3 Entitätsklassen

435

23.2.4 Entity Framework Core-Kontextklasse

436

23.2.5 Startcode

436

23.2.6 Erzeugte Datenbank

437

23.2.7 Datenzugriffscode

439

23.2.8 Benutzeroberfläche

443

23.3 Entity Framework Core in einer Xamarin-Cross-Platform-App

444

23.3.1 Das Fallbeispiel “MiracleList Light“ 424

15

23.3.2 Architektur

446

23.3.3 Entitätsklassen

448

23.3.4 Entity Framework Core-Kontextklasse

448

23.3.5 Startcode

450

23.3.6 Erzeugte Datenbank

450

23.3.7 Datenzugriffscode

450

23.3.8 Benutzeroberfläche

454

23.4 N:M-Beziehungen zu sich selbst

455

24 Quellen im Internet

461

Index

463

Leere Seite

2

 

© 2009-2024 ciando GmbH