Foreword |
|
xxi | |
Preface |
|
xxiii | |
Acknowledgments |
|
xxv | |
About This Book |
|
xxvii | |
About The Author |
|
xxxii | |
About The Cover Illustration |
|
xxxiii | |
|
|
1 | (188) |
|
1 Introduction to Entity Framework Core |
|
|
3 | (24) |
|
1.1 What you'll learn from this book |
|
|
4 | (1) |
|
1.2 My "lightbulb moment" with Entity Framework |
|
|
5 | (1) |
|
1.3 Some words for existing EF6.x developers |
|
|
6 | (1) |
|
1.4 An overview of EF Core |
|
|
7 | (1) |
|
|
7 | (1) |
|
|
8 | (1) |
|
1.6 Your first EF Core application |
|
|
9 | (2) |
|
|
9 | (1) |
|
Creating your own NET Core console app with EF Core |
|
|
10 | (1) |
|
1.7 The database that MyFirstEfCoreApp will access |
|
|
11 | (2) |
|
1.8 Setting up the MyFirstEfCoreApp application |
|
|
13 | (2) |
|
The classes that map to the database: Book and Author |
|
|
13 | (1) |
|
The application's DbContext |
|
|
14 | (1) |
|
1.9 Looking under the hood of EF Core |
|
|
15 | (8) |
|
|
15 | (2) |
|
Reading data from the database |
|
|
17 | (3) |
|
|
20 | (3) |
|
1.10 The stages of development of EF Core |
|
|
23 | (1) |
|
1.11 Should you use EF Core in your next project? |
|
|
24 | (2) |
|
.NET is the future software platform, and it's fast! |
|
|
24 | (1) |
|
Open source and open communication |
|
|
24 | (1) |
|
Multiplatform applications and development |
|
|
24 | (1) |
|
Rapid development and good features |
|
|
25 | (1) |
|
|
25 | (1) |
|
|
25 | (1) |
|
1.12 When should you not use EF Core? |
|
|
26 | (1) |
|
|
27 | (34) |
|
2.1 Setting the scene: Our book-selling site |
|
|
28 | (7) |
|
The Book App's relational database |
|
|
28 | (3) |
|
Other relationship types not covered in this chapter |
|
|
31 | (1) |
|
The database showing all the tables |
|
|
32 | (1) |
|
The classes that EF Core maps to the database |
|
|
33 | (2) |
|
2.2 Creating the application's DbContext |
|
|
35 | (3) |
|
Defining the application's DbContext: EfCoreContext |
|
|
35 | (1) |
|
Creating an instance of the application's DbContext |
|
|
35 | (2) |
|
Creating a database for your own application |
|
|
37 | (1) |
|
2.3 Understanding database queries |
|
|
38 | (2) |
|
Application's DbContext property access |
|
|
39 | (1) |
|
A series of LINQ/EF Core commands |
|
|
39 | (1) |
|
|
39 | (1) |
|
The two types of database queries |
|
|
40 | (1) |
|
|
40 | (7) |
|
Eager loading: Loading relationships with the primary entity class |
|
|
40 | (3) |
|
Explicit loading: Loading relationships after the primary entity class |
|
|
43 | (1) |
|
Select loading: Loading specific parts of primary entity class and any relationships |
|
|
44 | (1) |
|
Lazy loading: Loading relationships as required |
|
|
45 | (2) |
|
2.5 Using client vs. server evaluation: Adapting data at the last stage of a query |
|
|
47 | (2) |
|
2.6 Building complex queries |
|
|
49 | (3) |
|
2.7 Introducing the architecture of the Book App |
|
|
52 | (2) |
|
2.8 Adding sorting, filtering, and paging |
|
|
54 | (4) |
|
Sorting books by price, publication date, and customer ratings |
|
|
54 | (1) |
|
Filtering books by publication year, categories, and customer ratings |
|
|
55 | (1) |
|
Other filtering options: Searching text for a specific string |
|
|
56 | (2) |
|
Paging the books in the list |
|
|
58 | (1) |
|
2.9 Putting it all together: Combining Query Objects |
|
|
58 | (3) |
|
3 Changing the database content |
|
|
61 | (33) |
|
3.1 Introducing EF Core's entity State |
|
|
62 | (1) |
|
3.2 Creating new rows in a table |
|
|
62 | (5) |
|
Creating a single entity on its own |
|
|
63 | (1) |
|
Creating a book with a review |
|
|
64 | (3) |
|
3.3 Updating database rows |
|
|
67 | (7) |
|
Handling disconnected updates in a web application |
|
|
69 | (5) |
|
3.4 Handling relationships in updates |
|
|
74 | (14) |
|
Principal and dependent relationships |
|
|
75 | (1) |
|
Updating one-to-one relationships: Adding a PriceOffer to a book |
|
|
76 | (4) |
|
Updating one-to-many relationships: Adding a review to a book |
|
|
80 | (3) |
|
Updating a many-to-many relationship |
|
|
83 | (4) |
|
Advanced feature: Updating relationships via foreign keys |
|
|
87 | (1) |
|
|
88 | (6) |
|
Soft-delete approach: Using a global query filter to hide entities |
|
|
88 | (2) |
|
Deleting a dependent-only entity with no relationships |
|
|
90 | (1) |
|
Deleting a principal entity that has relationships |
|
|
90 | (1) |
|
Deleting a book with its dependent relationships |
|
|
91 | (3) |
|
4 Using EF Core in business logic |
|
|
94 | (31) |
|
4.1 The questions to ask and the decisions you need to make before you start coding |
|
|
95 | (2) |
|
The three levels of complexity of your business logic code |
|
|
95 | (2) |
|
4.2 Complex business logic example: Processing an order for books |
|
|
97 | (1) |
|
4.3 Using a design pattern to implement complex business logic |
|
|
98 | (1) |
|
Five guidelines for building business logic that uses EF Core |
|
|
98 | (1) |
|
4.4 Implementing the business logic for processing an order |
|
|
99 | (12) |
|
Guideline 1 Business logic has first call on defining the database structure |
|
|
100 | (1) |
|
Guideline 2 Business logic should have no distractions |
|
|
101 | (1) |
|
Guideline 3 Business logic should think that it's working on in-memory data |
|
|
102 | (3) |
|
Guideline 4 Isolate the database access code into a separate project |
|
|
105 | (1) |
|
Guideline 5 Business logic shouldn't call EF Core's Save Changes |
|
|
106 | (2) |
|
Putting it all together: Calling the order-processing business logic |
|
|
108 | (1) |
|
Placing an order in the Book App |
|
|
109 | (2) |
|
The pros and cons of the complex business logic pattern |
|
|
111 | (1) |
|
4.5 Simple business logic example: ChangePriceOfferService |
|
|
111 | (2) |
|
My design approach for simple business logic |
|
|
112 | (1) |
|
Writing the ChangePriceOfferService code |
|
|
112 | (1) |
|
The pros and cons of this business logic pattern |
|
|
113 | (1) |
|
4.6 Validation business logic example: Adding review to a book, with checks |
|
|
113 | (2) |
|
The pros and cons of this business logic pattern |
|
|
114 | (1) |
|
4.7 Adding extra features to your business logic handling |
|
|
115 | (10) |
|
Validating the data that you write to the database |
|
|
115 | (4) |
|
Using transactions to daisy-chain a sequence of business logic code |
|
|
119 | (3) |
|
Using the RunnerTransact2WriteDb class |
|
|
122 | (3) |
|
5 Using EF Core in ASP.NET Core web applications |
|
|
125 | (34) |
|
5.1 Introducing ASP.NET Core |
|
|
126 | (1) |
|
5.2 Understanding the architecture of the Book App |
|
|
126 | (1) |
|
5.3 Understanding dependency injection |
|
|
127 | (4) |
|
Why you need to learn about DI in ASP.NET Core |
|
|
128 | (1) |
|
A basic example of dependency injection in ASP.NET Core |
|
|
128 | (1) |
|
The lifetime of a service created by DI |
|
|
129 | (2) |
|
Special considerations for Blazor Server applications |
|
|
131 | (1) |
|
5.4 Making the application's DbContext available via DI |
|
|
131 | (3) |
|
Providing information on the database's location |
|
|
131 | (1) |
|
Registering your application's DbContext with the DI provider |
|
|
132 | (2) |
|
Registering a DbContext Factory with the DI provider |
|
|
134 | (1) |
|
5.5 Calling your database access code from ASP.NET Core |
|
|
134 | (2) |
|
A summary of how ASP.NET Core MVC works and the terms it uses |
|
|
135 | (1) |
|
Where does the EF Core code live in the Book App? |
|
|
135 | (1) |
|
5.6 Implementing the book list query page |
|
|
136 | (4) |
|
Injecting an instance of the application's DbContext via DI |
|
|
137 | (1) |
|
Using the DbContext Factory to create an instance of a DbContext |
|
|
138 | (2) |
|
5.7 Implementing your database methods as a DI service |
|
|
140 | (6) |
|
Registering your class as a DI service |
|
|
141 | (1) |
|
Injecting ChangePubDateService into the ASP.NET action method |
|
|
142 | (1) |
|
Improving registering your database access classes as services |
|
|
143 | (3) |
|
5.8 Deploying an ASP.NET Core application with a database |
|
|
146 | (1) |
|
Knowing where the database is on the web server |
|
|
146 | (1) |
|
Creating and migrating the database |
|
|
147 | (1) |
|
5.9 Using EF Core's migration feature to change the database's structure |
|
|
147 | (4) |
|
Updating your production database |
|
|
147 | (1) |
|
Having your application migrate your database on startup |
|
|
148 | (3) |
|
5.10 Using async/await for better scalability |
|
|
151 | (3) |
|
Why async/await is useful in a web application using EF Core |
|
|
151 | (1) |
|
Where should you use async/await with database accesses? |
|
|
152 | (1) |
|
Changing over to async/await versions of EF Core commands |
|
|
153 | (1) |
|
5.11 Running parallel tasks: How to provide the DbContext |
|
|
154 | (5) |
|
Obtaining an instance of your application's DbContext to run in parallel |
|
|
155 | (1) |
|
Running a background service in ASP.NET Core |
|
|
156 | (1) |
|
Other ways of obtaining a new instance of the application's DbContext |
|
|
157 | (2) |
|
6 Tips and techniques for reading and writing with EF Core |
|
|
159 | (30) |
|
6.1 Reading from the database |
|
|
160 | (20) |
|
Exploring the relational fixup stage in a query |
|
|
160 | (1) |
|
Understanding what AsNoTracking and its variant do |
|
|
161 | (2) |
|
Reading in hierarchical data efficiently |
|
|
163 | (2) |
|
Understanding how the Include method works |
|
|
165 | (1) |
|
Making loading navigational collections fail-safe |
|
|
166 | (2) |
|
Using Global Query Filters in real-world situations |
|
|
168 | (4) |
|
Considering LINQ commands that need special attention |
|
|
172 | (1) |
|
Using AutoMapper to automate building Select queries |
|
|
173 | (3) |
|
Evaluating how EF Core creates an entity class when reading data in |
|
|
176 | (4) |
|
6.2 Writing to the database with EF Core |
|
|
180 | (9) |
|
Evaluating how EF Core writes entities/relationships to the database |
|
|
181 | (1) |
|
Evaluating how DbContext handles writing out entities/relationships |
|
|
182 | (4) |
|
A quick way to copy data with relationships |
|
|
186 | (1) |
|
A quick way to delete an entity |
|
|
187 | (2) |
|
|
189 | (192) |
|
7 Configuring nonrelational properties |
|
|
191 | (35) |
|
7.1 Three ways of configuring EF Core |
|
|
192 | (1) |
|
7.2 A worked example of configuring EF Core |
|
|
193 | (3) |
|
7.3 Configuring by convention |
|
|
196 | (2) |
|
Conventions for entity classes |
|
|
196 | (1) |
|
Conventions for parameters in an entity class |
|
|
196 | (1) |
|
Conventions for name, type, and size |
|
|
197 | (1) |
|
By convention, the nullability of a property is based on NET type |
|
|
197 | (1) |
|
An EF Core naming convention identifies primary keys |
|
|
198 | (1) |
|
7.4 Configuring via Data Annotations |
|
|
198 | (1) |
|
Using annotations from, System. ComponentModel.DataAnnotations |
|
|
199 | (1) |
|
Using annotations from System. ComponentModel.DataAnnotations.Schema |
|
|
199 | (1) |
|
7.5 Configuring via the Fluent API |
|
|
199 | (3) |
|
7.6 Excluding properties and classes from the database |
|
|
202 | (1) |
|
Excluding a class or property via Data Annotations |
|
|
202 | (1) |
|
Excluding a class or property via the Fluent API |
|
|
203 | (1) |
|
7.7 Setting database column type, size, and nullability |
|
|
203 | (1) |
|
7.8 Value conversions: Changing data to/from the database |
|
|
204 | (2) |
|
7.9 The different ways of configuring the primary key |
|
|
206 | (2) |
|
Configuring a primary key via Data Annotations |
|
|
206 | (1) |
|
Configuring a primary key via the Fluent API |
|
|
206 | (1) |
|
Configuring an entity as read-only |
|
|
207 | (1) |
|
7.10 Adding indexes to database columns |
|
|
208 | (1) |
|
7.11 Configuring the naming on the database side |
|
|
209 | (2) |
|
|
209 | (1) |
|
Configuring the schema name and schema groupings |
|
|
210 | (1) |
|
Configuring the database column names in a table |
|
|
210 | (1) |
|
7.12 Configuring Global Query Filters |
|
|
211 | (1) |
|
7.13 Applying Fluent API commands based on the database provider type |
|
|
211 | (1) |
|
7.14 Shadow properties: Hiding column data inside EF Core |
|
|
212 | (2) |
|
Configuring shadow properties |
|
|
212 | (1) |
|
Accessing shadow properties |
|
|
213 | (1) |
|
7.15 Backing fields: Controlling access to data in an entity class |
|
|
214 | (4) |
|
Creating a simple backing field accessed by a read/write property |
|
|
215 | (1) |
|
Creating a read-only column |
|
|
215 | (1) |
|
Concealing a person's date of birth: Hiding data inside a class |
|
|
215 | (1) |
|
Configuring backing fields |
|
|
216 | (2) |
|
7.16 Recommendations for using EF Core's configuration |
|
|
218 | (8) |
|
Use By Convention configuration first |
|
|
219 | (1) |
|
Use validation Data Annotations wherever possible |
|
|
219 | (1) |
|
Use the Fluent API for anything else |
|
|
220 | (1) |
|
Automate adding Fluent API commands by class/property signatures |
|
|
220 | (6) |
|
8 Configuring relationships |
|
|
226 | (42) |
|
8.1 Defining some relationship terms |
|
|
227 | (1) |
|
8.2 What navigational properties do you need? |
|
|
228 | (1) |
|
8.3 Configuring relationships |
|
|
229 | (1) |
|
8.4 Configuring relationships By Convention |
|
|
229 | (5) |
|
What makes a class an entity class? |
|
|
229 | (1) |
|
An example of an entity class with navigational properties |
|
|
230 | (1) |
|
How EF Core finds foreign keys By Convention |
|
|
231 | (1) |
|
Nullability of foreign keys: Required or optional dependent relationships |
|
|
232 | (1) |
|
Foreign keys: What happens if you leave them out? |
|
|
232 | (2) |
|
When does By Convention configuration not work? |
|
|
234 | (1) |
|
8.5 Configuring relationships by using Data Annotations |
|
|
234 | (2) |
|
The Foreign Key Data Annotation |
|
|
234 | (1) |
|
The Inverse Property Data Annotation |
|
|
235 | (1) |
|
8.6 Fluent API relationship configuration commands |
|
|
236 | (7) |
|
Creating a one-to-one relationship |
|
|
237 | (2) |
|
Creating a one-to-many relationship |
|
|
239 | (1) |
|
Creating a many-to-many relationship |
|
|
240 | (3) |
|
8.7 Controlling updates to collection navigational properties |
|
|
243 | (2) |
|
8.8 Additional methods available in Fluent API relationships |
|
|
245 | (6) |
|
OnDelete: Changing the delete action of a dependent entity |
|
|
245 | (3) |
|
IsRequired: Defining the nullability of the foreign key |
|
|
248 | (1) |
|
Has Principal Key: Using an alternate unique key |
|
|
249 | (2) |
|
Less-used options in Fluent API relationships |
|
|
251 | (1) |
|
8.9 Alternative ways of mapping entities to database tables |
|
|
251 | (17) |
|
Owned types: Adding a normal class into an entity class |
|
|
252 | (4) |
|
Table per hierarchy (TPH): Placing inherited classes into one table |
|
|
256 | (5) |
|
Table per Type (TPT): Each class has its own table |
|
|
261 | (2) |
|
Table splitting: Mapping multiple entity classes to the same table |
|
|
263 | (1) |
|
Property bag: Using a dictionary as an entity class |
|
|
264 | (4) |
|
9 Handling database migrations |
|
|
268 | (38) |
|
9.1 How this chapter is organized |
|
|
269 | (1) |
|
9.2 Understanding the complexities of changing your application's database |
|
|
269 | (2) |
|
A view of what databases need updating |
|
|
270 | (1) |
|
Handling a migration that can lose data |
|
|
271 | (1) |
|
9.3 Part 1: Introducing the three approaches to creating a migration |
|
|
271 | (1) |
|
9.4 Creating a migration by using EF Core's add migration command |
|
|
272 | (8) |
|
Requirements before running any EF Core migration command |
|
|
275 | (1) |
|
Running the add migration command |
|
|
275 | (1) |
|
Seeding your database via an EF Core migration |
|
|
276 | (1) |
|
Handling EF Core migrations with multiple developers |
|
|
277 | (1) |
|
Using a custom migration table to allow multiple DbContexts to one database |
|
|
278 | (2) |
|
9.5 Editing an EF Core migration to handle complex situations |
|
|
280 | (7) |
|
Adding and removing MigrationBuilder methods inside the migration class |
|
|
281 | (1) |
|
Adding SQL commands to a migration |
|
|
282 | (2) |
|
Adding your own custom migration commands |
|
|
284 | (1) |
|
Altering a migration to work for multiple database types |
|
|
285 | (2) |
|
9.6 Using SQL scripts to build migrations |
|
|
287 | (5) |
|
Using SQL database comparison tools to produce migration |
|
|
287 | (2) |
|
Handcoding SQL change scripts to migrate the database |
|
|
289 | (2) |
|
Checking that your SQL change scripts matches EF Core's database model |
|
|
291 | (1) |
|
9.7 Using EF Core's reverse-engineering tool |
|
|
292 | (3) |
|
Running EF Core's reverse-engineering command |
|
|
294 | (1) |
|
Installing and running EF Core Power Tools reverse-engineering command |
|
|
294 | (1) |
|
Updating your entity classes and DbContext when the database changes |
|
|
294 | (1) |
|
9.8 Part 2: Applying your migrations to a database |
|
|
295 | (5) |
|
Calling EF Core's Database. Migrate method from your main application |
|
|
296 | (2) |
|
Executing EF Core's Database.Migrate method from a standalone application |
|
|
298 | (1) |
|
Applying an EF Core's migration via an SQL change script |
|
|
298 | (2) |
|
Applying SQL change scripts by using a migration tool |
|
|
300 | (1) |
|
9.9 Migrating a database while the application is running |
|
|
300 | (6) |
|
Handling a migration that doesn't contain an application-breaking change |
|
|
302 | (1) |
|
Handling application-breaking changes when you can't stop the app |
|
|
302 | (4) |
|
10 Configuring advanced features and handling concurrency conflicts |
|
|
306 | (34) |
|
10.1 DbFunction: Using user-defined functions (UDFs) with EF Core |
|
|
307 | (6) |
|
Configuring a scalar-valued UDF |
|
|
308 | (2) |
|
Configuring a table-valued UDF |
|
|
310 | (1) |
|
Adding your UDF code to the database |
|
|
311 | (1) |
|
Using a registered UDF in your database queries |
|
|
312 | (1) |
|
10.2 Computed column: A dynamically calculated column value |
|
|
313 | (2) |
|
10.3 Setting a default value for a database column |
|
|
315 | (4) |
|
Using the Has Default Value method to add a constant value for a column |
|
|
316 | (1) |
|
Using the Has Default Value Sql method to add an SQL command for a column |
|
|
317 | (1) |
|
Using the Has Value Generator method to assign a value generator to a property |
|
|
318 | (1) |
|
10.4 Sequences: Providing numbers in a strict order |
|
|
319 | (1) |
|
10.5 Marking database-generated properties |
|
|
320 | (3) |
|
Marking a column that's generated on an addition or update |
|
|
321 | (1) |
|
Marking a column's value as set on insert of a new row |
|
|
322 | (1) |
|
Marking a column/property as "normal" |
|
|
322 | (1) |
|
10.6 Handling simultaneous updates: Concurrency conflicts |
|
|
323 | (17) |
|
Why do concurrency conflicts matter'? |
|
|
323 | (2) |
|
EF Core's concurrency conflict-handling features |
|
|
325 | (6) |
|
Handling a DbUpdate Concurrency Exception |
|
|
331 | (3) |
|
The disconnected concurrent update issue |
|
|
334 | (6) |
|
11 Going deeper into the DbContext |
|
|
340 | (41) |
|
11.1 Overview of the DbContext class's properties |
|
|
341 | (1) |
|
11.2 Understanding how EF Core tracks changes |
|
|
341 | (2) |
|
11.3 Looking at commands that change an entity's State |
|
|
343 | (6) |
|
The Add command: Inserting a new row into the database |
|
|
344 | (1) |
|
The Remove method: Deleting a row from the database |
|
|
344 | (1) |
|
Modifying an entity class by changing the data in that entity class |
|
|
345 | (1) |
|
Modifying an entity class by calling the Update method |
|
|
346 | (1) |
|
The Attach method: Start tracking an existing untracked entity class |
|
|
347 | (1) |
|
Setting the State of an entity directly |
|
|
347 | (1) |
|
TrackGraph: Handling disconnected updates with relationships |
|
|
348 | (1) |
|
11.4 SaveChanges and its use of ChangeTracker.DetectChanges |
|
|
349 | (14) |
|
How SaveChanges finds all the State changes |
|
|
350 | (1) |
|
What to do if ChangeTracker.DetectChanges is taking too long |
|
|
351 | (5) |
|
Using the entities' State within the SaveChanges method |
|
|
356 | (2) |
|
Catching entity class's State changes via events |
|
|
358 | (3) |
|
Triggering events when SaveChanges/SaveChangesAsync is called |
|
|
361 | (1) |
|
|
362 | (1) |
|
11.5 Using SQL commands in an EF Core application |
|
|
363 | (5) |
|
FromSqlRaw/FromSqllnterpolated: Using SQL in an EF Core query |
|
|
364 | (1) |
|
ExecuteSqlRaw/ExecuteSqllnterpolated: Executing a nonquery command |
|
|
365 | (1) |
|
AsSqlQuery Fluent API method: Mapping entity classes to queries |
|
|
365 | (2) |
|
Reload: Used after ExecuteSql commands |
|
|
367 | (1) |
|
GetDbConnection: Running your own SQL commands |
|
|
367 | (1) |
|
11.6 Accessing information about the entity classes and database tables |
|
|
368 | (4) |
|
Using context.Entry (entity). Metadata to reset primary keys |
|
|
369 | (2) |
|
Using context.Model to get database information |
|
|
371 | (1) |
|
11.7 Dynamically changing the DbContext's connection string |
|
|
372 | (1) |
|
11.8 Handling database connection problems |
|
|
373 | (8) |
|
Handling database transactions with EF Core's execution strategy |
|
|
374 | (1) |
|
Altering or writing your own execution strategy |
|
|
375 | (6) |
|
|
|
12 Using entity events to solve business problems |
|
|
381 | (24) |
|
12.1 Using events to solve business problems |
|
|
382 | (2) |
|
Example of using domain events |
|
|
382 | (1) |
|
Example of integration events |
|
|
383 | (1) |
|
12.2 Defining where domain events and integration events are useful |
|
|
384 | (1) |
|
12.3 Where might you use events with EF Core? |
|
|
385 | (2) |
|
Pro: Follows the SoC design principle |
|
|
386 | (1) |
|
Pro: Makes database updates robust |
|
|
386 | (1) |
|
Con: Makes your application more complex |
|
|
387 | (1) |
|
Con: Makes following the flow of the code more difficult |
|
|
387 | (1) |
|
12.4 Implementing a domain event system with EF Core |
|
|
387 | (9) |
|
Create some domain events classes to be triggered |
|
|
388 | (1) |
|
Add code to the entity classes to hold the domain events |
|
|
389 | (1) |
|
Alter the entity class to detect a change to trigger an event on |
|
|
390 | (1) |
|
Create event handlers that are matched to the domain events |
|
|
390 | (1) |
|
Build an Event Runner that finds and runs the correct event handler |
|
|
391 | (3) |
|
Override SaveChanges and insert the Event Runner before SaveChanges is called |
|
|
394 | (1) |
|
Register the Event Runner and all the event handlers |
|
|
395 | (1) |
|
12.5 Implementing an integration event system with EF Core |
|
|
396 | (4) |
|
Building a service that communicates with the warehouse |
|
|
398 | (1) |
|
Overriding SaveChanges to handle the integration event |
|
|
399 | (1) |
|
12.6 Improving the domain event and integration event implementations |
|
|
400 | (5) |
|
Generalizing events: Running before, during, and after the call to SaveChanges |
|
|
401 | (1) |
|
Adding support for async event handlers |
|
|
402 | (1) |
|
Handling multiple event banders for the same event |
|
|
403 | (1) |
|
Handling event sagas in which one event kicks off another event |
|
|
403 | (2) |
|
13 Domain-Driven Design and other architectural approaches |
|
|
405 | (33) |
|
13.1 A good software architecture makes it easier to build and maintain your application |
|
|
406 | (1) |
|
13.2 The Book App's evolving architecture |
|
|
406 | (4) |
|
Building a modular monolith to enforce the SoC principles |
|
|
408 | (1) |
|
Using DDD principles both architecturally and on the entity classes |
|
|
409 | (1) |
|
Applying a clean architecture as described by Robert C. Martin |
|
|
410 | (1) |
|
13.3 Introduction to DDD at the entity class level |
|
|
410 | (1) |
|
13.4 Altering the Book App entities to follow the DDD approach |
|
|
411 | (10) |
|
Changing the properties in the Book entity to read-only |
|
|
411 | (2) |
|
Updating the Book entity properties via methods in the entity class |
|
|
413 | (2) |
|
Controlling how the Book entity is created |
|
|
415 | (1) |
|
Understanding the differences between an entity and a value object |
|
|
416 | (1) |
|
Minimizing the relationships between entity classes |
|
|
416 | (1) |
|
|
417 | (1) |
|
Deciding when the business logic shouldn't be run inside an entity |
|
|
418 | (2) |
|
Applying DDD's bounded context to your application's DbContext |
|
|
420 | (1) |
|
13.5 Using your DDD-styled entity classes in your application |
|
|
421 | (7) |
|
Calling the AddPromotion access method via a repository pattern |
|
|
422 | (2) |
|
Calling the AddPromotion access method via a class-to-method-call library |
|
|
424 | (2) |
|
Adding a Review to the Book entity class via a repository pattern |
|
|
426 | (1) |
|
Adding a Review to the Book entity class via a class-to-method-call library |
|
|
427 | (1) |
|
13.6 The downside of DDD entities: Too many access methods |
|
|
428 | (1) |
|
13.7 Getting around performance issues in DDD-styled entities |
|
|
429 | (4) |
|
Allow database code into your entity classes |
|
|
430 | (1) |
|
Make the Review constructor public and write nonentity code to add a Review |
|
|
431 | (1) |
|
Use domain events to ask an event handler to add a review to the database |
|
|
432 | (1) |
|
13.8 Three architectural approaches: Did they work? |
|
|
433 | (5) |
|
A modular monolith approach that enforces SoC by using projects |
|
|
433 | (1) |
|
DDD principles, both architecturally and on the entity classes |
|
|
434 | (1) |
|
Clean architecture as described by Robert C. Martin |
|
|
435 | (3) |
|
14 EF Core performance tuning |
|
|
438 | (25) |
|
14.1 Part 1: Deciding which performance issues to fix |
|
|
439 | (3) |
|
"Don't performance-tune too early" doesn't mean you stop thinking |
|
|
439 | (1) |
|
How do you decide what's slow and needs performance tuning? |
|
|
440 | (1) |
|
The cost offinding and fixing performance issues |
|
|
441 | (1) |
|
14.2 Part 2: Techniques for diagnosing a performance issue |
|
|
442 | (4) |
|
Stage 1 Get a good overview, measuring the user's experience |
|
|
443 | (1) |
|
Stage 2 Find all the database code involved in the feature you 're tuning |
|
|
444 | (1) |
|
Stage 3 Inspect the SQL code to find poor performance |
|
|
444 | (2) |
|
14.3 Part 3: Techniques for fixing performance issues |
|
|
446 | (1) |
|
14.4 Using good patterns makes your application perform well |
|
|
447 | (3) |
|
Using Select loading to load only the columns you need |
|
|
447 | (1) |
|
Using paging and/or filtering of searches to reduce the rows you load |
|
|
448 | (1) |
|
Warning: Lazy loading will affect database performance |
|
|
448 | (1) |
|
Always adding the AsNoTracking method to read-only queries |
|
|
449 | (1) |
|
Using the async version ofEF Core commands to improve scalability |
|
|
449 | (1) |
|
Ensuring that your database access code is isolated/decoupled |
|
|
449 | (1) |
|
14.5 Performance antipatterns: Database queries |
|
|
450 | (5) |
|
Antipattern: Not minimizing the number of calls to the database |
|
|
450 | (1) |
|
Antipattern: Missing indexes from a property that you want to search on |
|
|
451 | (1) |
|
Antipattern: Not using the fastest way to load a single entity |
|
|
452 | (1) |
|
Antipattern: Allowing too much of a data query to be moved into the software side |
|
|
453 | (1) |
|
Antipattern: Not moving calculations into the database |
|
|
453 | (1) |
|
Antipattern: Not replacing suboptimal SQL in a LINQ query |
|
|
454 | (1) |
|
Antipattern: Not precompiling frequently used queries |
|
|
454 | (1) |
|
14.6 Performance antipatterns: Writes |
|
|
455 | (4) |
|
Antipattern: Calling SaveChanges multiple times |
|
|
456 | (1) |
|
Antipattern: Making DetectChanges work too hard |
|
|
457 | (1) |
|
Antipattern: Not using HashSet<T> for navigational collection properties |
|
|
458 | (1) |
|
Antipattern: Using the Update method when you want to change only part of the entity |
|
|
458 | (1) |
|
Antipattern: Startup issue--Using one large DbContext |
|
|
458 | (1) |
|
14.7 Performance patterns: Scalability of database accesses |
|
|
459 | (4) |
|
Using pooling to reduce the cost of a new application's DbContext |
|
|
460 | (1) |
|
Adding scalability with little effect on overall speed |
|
|
460 | (1) |
|
Helping your database scalability by making your queries simple |
|
|
461 | (1) |
|
Scaling up the database server |
|
|
461 | (1) |
|
Picking the right architecture for applications that need high scalability |
|
|
461 | (2) |
|
15 Master class on performance-tuning database queries |
|
|
463 | (29) |
|
15.1 The test setup and a summary of the four performance approaches |
|
|
464 | (2) |
|
15.2 Good LINQ approach: Using an EF Core Select query |
|
|
466 | (3) |
|
15.3 LINQ+UDFs approach: Adding some SQL to your LINQ code |
|
|
469 | (2) |
|
15.4 SQL+Dapper: Creating your own SQL |
|
|
471 | (2) |
|
15.5 LINQ+caching approach: Precalculating cosdy query parts |
|
|
473 | (15) |
|
Adding a way to detect changes that affect the cached values |
|
|
475 | (2) |
|
Adding code to update the cached values |
|
|
477 | (3) |
|
Adding cache properties to the Book entity with concurrency handling |
|
|
480 | (6) |
|
Adding a checking/healing system to your event system |
|
|
486 | (2) |
|
15.6 Comparing the four performance approaches with development effort |
|
|
488 | (1) |
|
15.7 Improving database scalability |
|
|
489 | (3) |
|
16 Cosmos DB, CQRS, and other database types |
|
|
492 | (33) |
|
16.1 The differences between relational and NoSQL databases |
|
|
493 | (1) |
|
16.2 Introduction to Cosmos DB and its EF Core provider |
|
|
494 | (1) |
|
16.3 Building a Command and Query Responsibility Segregation (CQRS) system using Cosmos DB |
|
|
495 | (2) |
|
16.4 The design of a two-database CQRS architecture application |
|
|
497 | (8) |
|
Creating an event to trigger when the SQL Book entity changes |
|
|
498 | (1) |
|
Adding events to the Book entity send integration events |
|
|
499 | (1) |
|
Using the EfCore. GenericEventRunner to override your BookDbContext |
|
|
500 | (1) |
|
Creating the Cosmos entity classes and DbContext |
|
|
500 | (2) |
|
Creating the Cosmos event handlers |
|
|
502 | (3) |
|
16.5 Understanding the structure and data of a Cosmos DB account |
|
|
505 | (2) |
|
The Cosmos DB structure, as seen from EF Core |
|
|
505 | (1) |
|
How the CosmosClass is stored in Cosmos DB |
|
|
506 | (1) |
|
16.6 Displaying books via Cosmos DB |
|
|
507 | (7) |
|
Cosmos DB differences from relational databases |
|
|
508 | (3) |
|
Cosmos DB/EF Core difference: Migrating a Cosmos database |
|
|
511 | (1) |
|
EF Core 5 Cosmos DB database provider limitations |
|
|
512 | (2) |
|
16.7 Was using Cosmos DB worth the effort? Yes! |
|
|
514 | (8) |
|
Evaluating the performance of the two-database CQRS in the Book App |
|
|
515 | (3) |
|
Fixing the features that EF Core 5 Cosmos DB database provider couldn't handle |
|
|
518 | (3) |
|
How difficult would it be to use this two-database CQRS design in your application? |
|
|
521 | (1) |
|
16.8 Differences in other database types |
|
|
522 | (3) |
|
17 Unit testing EF Core applications |
|
|
525 | (36) |
|
17.1 An introduction to the unit test setup |
|
|
527 | (3) |
|
The test environment: xUnit unit test library |
|
|
528 | (1) |
|
A library I created to help with unit testing EF Core applications |
|
|
529 | (1) |
|
17.2 Getting your application's DbContext ready for unit testing |
|
|
530 | (2) |
|
The application's DbContext options are provided via its constructor |
|
|
530 | (1) |
|
Setting an application's DbContext options via OnConfiguring |
|
|
531 | (1) |
|
17.3 Three ways to simulate the database when testing EF Core applications |
|
|
532 | (2) |
|
17.4 Choosing between a production-type database and an SQLite in-memory database |
|
|
534 | (2) |
|
17.5 Using a production-type database in your unit tests |
|
|
536 | (8) |
|
Providing a connection string to the database to use for the unit test |
|
|
536 | (1) |
|
Providing a database per test class to allow xUnit to run tests in parallel |
|
|
537 | (3) |
|
Making sure that the database's schema is up to date and the database is empty |
|
|
540 | (2) |
|
Mimicking the database setup that EF Core migration would deliver |
|
|
542 | (2) |
|
17.6 Using an SQLite in-memory database for unit testing |
|
|
544 | (2) |
|
17.7 Stubbing or mocking an EF Core database |
|
|
546 | (3) |
|
17.8 Unit testing a Cosmos DB database |
|
|
549 | (2) |
|
17.9 Seeding a database with test data to test your code correctly |
|
|
551 | (1) |
|
17.10 Solving the problem of one database access breaking another stage of your test |
|
|
552 | (3) |
|
Test code using ChangeTracker. Clear in a disconnected state |
|
|
553 | (1) |
|
Test code by using multiple DbContext instances in a disconnected state |
|
|
554 | (1) |
|
17.11 Capturing the database commands sent to a database |
|
|
555 | (6) |
|
Using the LogTo option extension to filter and capture EF Core logging |
|
|
555 | (3) |
|
Using the ToQueryString method to show the SQL generated from a LINQ query |
|
|
558 | (3) |
Appendix A A brief introduction to LINQ |
|
561 | (8) |
Index |
|
569 | |