Entity Framework Core in Action
Jon P Smith
  • July 2018
  • ISBN 9781617294563
  • 520 pages
  • printed in black & white

An expertly written guide to EF Core—quite possibly the only reference you’ll ever need.

Stephen Byrne, Action Point

Entity Framework Core in Action teaches you how to access and update relational data from .NET applications. Following the crystal-clear explanations, real-world examples, and around 100 diagrams, you’ll discover time-saving patterns and best practices for security, performance tuning, and unit testing.

Table of Contents detailed table of contents

preface

acknowledgments

about this book

about the author

about the cover illustration

Part 1: Getting started

1. Introduction to Entity FrameworkCore

1.1. What you’ll learn from this book

1.2. My “lightbulb moment” with Entity Framework

1.3. Some words for existing EF6.x developers

1.4. An overview of EF Core

1.4.1. The downsides of O/RMs

1.5. What about NoSQL?

1.6. Your first EF Core application

1.6.1. What you need to install

1.6.2. Creating your own .NET Core console app with EF Core

1.7. The database that MyFirstEfCoreApp will access

1.8. Setting up the MyFirstEfCoreApp application

1.8.1. The classes that map to the database—​Book and Author

1.8.2. The application’s DbContext

1.9. Looking under the hood of EF Core

1.9.1. Modeling the database

1.9.2. Reading data from the database

1.9.3. Updating the database

1.10. Should you use EF Core in your next project?

1.10.1. Latest generation

1.10.2. Multiplatform and open source

1.10.3. Rapid development

1.10.4. Well supported

1.10.5. Access to NuGet libraries

1.10.7. Stable library

1.10.8. Always high-performance

1.11. When should you not use EF Core?

2. Querying the database

2.1. Setting the scene—​our book-selling site

2.1.1. The book app’s relational database

2.1.2. Other relationship types not covered in this chapter

2.1.3. The final database showing all the tables

2.1.4. The classes that EF Core maps to the database

2.2. Creating the application’s DbContext

2.2.1. Defining the application’s DbContext: EfCoreContext

2.2.2. Creating an instance of the application’s DbContext

2.2.3. Creating a database for your own application

2.3. Understanding database queries

2.3.1. Application’s DbContext property access

2.3.2. A series of LINQ/EF Core commands

2.3.3. The execute command

2.4.1. Eager loading: loading relationships with the primary entity class

2.4.2. Explicit loading: loading relationships after the primary entity class

2.4.3. Select loading: loading specific parts of primary entity class and any relationships

2.5. Using client vs. server evaluation: moving part of your query into software

2.5.1. Creating the display string of a book’s authors

2.5.2. Understanding the limitations of client vs. server evaluation

2.6. Building complex queries

2.6.1. Building the book list query by using select loading

2.6.2. Introducing the architecture of the book app

2.7. Adding sorting, filtering, and paging

2.7.1. Sorting books by price, publication date, and customer ratings

2.7.2. Filtering books by publication year and customer ratings

2.7.3. Paging the books in the list

2.8. Putting it all together: combining query objects

3. Changing the database content

3.1. Introducing EF Core’s entity State

3.2. Creating new rows in a table

3.2.1. Creating a single entity on its own

3.2.2. Creating a book with a review

3.3. Updating database rows

3.3.1. Handling disconnected updates in a web application

3.4. Handling relationships in updates

3.4.1. Principal and dependent relationships

3.4.2. Updating one-to-one relationships—​adding a PriceOffer to a book

3.4.3. Updating one-to-many relationships—​adding a review to a book

3.4.4. Updating many-to-many relationships—​changing a book’s authors

3.4.5. Advanced feature—​updating relationships via foreign keys

3.5. Deleting entities

3.5.1. Using a soft delete—​using model-level query filters to “hide” entities

3.5.2. Deleting a dependent-only entity—​no relationships

3.5.3. Deleting a principal entity that has relationships

4. Using EF Core in business logic

4.1. Why is business logic so different from other code?

4.2. Our business need—​processing an order for books

4.2.1. The business rules that you need to implement

4.3. Using a design pattern to help implement business logic

4.3.1. Five guidelines for building business logic that uses EF Core

4.4. Implementing the business logic for processing an order

4.4.1. Guideline 1: Business logic has first call on defining the database tructure

4.4.2. Guideline 2: Business logic should have no distractions

4.4.3. Guideline 3: Business logic should think it’s working on in-memory data

4.4.4. Guideline 4: Isolate the database access code into a separate project

4.4.5. Guideline 5: Business logic shouldn’t call EF Core’s SaveChanges

4.4.6. Putting it all together—​calling the order-processing business logic

4.4.7. Any disadvantages of this business logic pattern?

4.5. Placing an order on the book app

4.6. Adding extra features to your business logic handling

4.6.1. Validating the data that you write to the database

4.6.2. Using transactions to daisy-chain a sequence of business logic code

5. Using EF Core in ASP.NET Core web applications

5.1. Introducing ASP.NET Core

5.2. Understanding the architecture of the book app

5.3. Understanding dependency injection

5.3.1. Why you need to learn about DI in ASP.NET Core

5.3.2. A basic example of dependency injection in ASP.NET Core

5.3.3. The lifetime of a service created by DI

5.4. Making the application’s DbContext available via DI

5.4.1. Providing information on the database’s location

5.4.2. Registering your application’s DbContext with the DI provider

5.5. Calling your database access code from ASP.NET Core

5.5.1. A summary of how ASP.NET Core works and the terms it uses

5.5.2. Where does the EF Core code live in the book app?

5.6. Implementing the book list query page

5.7. Implementing your database methods as a DI service

5.7.1. Registering your class as a DI service

5.7.2. Injecting ChangePubDateService into the ASP.NET action method

5.7.3. Improving registering your database access classes as services

5.8. Deploying an ASP.NET Core application with a database

5.8.1. Knowing where the database is on the web server

5.8.2. Creating and migrating the database

5.9. Using EF Core’s Migrate to change the database structure

5.9.1. Updating your production database

5.9.2. Having your application migrate your database on startup

5.10. Using async/await for better scalability

5.10.1. Why async/await is useful in a web application using EF Core

5.10.2. Where should you use async/await with database accesses?

5.10.3. Changing over to async/await versions of EF Core commands

5.11. Running parallel tasks: how to provide the DbContext

5.11.1. Other ways of obtaining a new instance of the application’s DbContext

Part 2: Entity Framework in depth

6. Configuring nonrelational properties

6.1. Three ways of configuring EF Core

6.2. A worked example of configuring EF Core

6.3. Configuring By Convention

6.3.1. Conventions for entity classes

6.3.2. Conventions for parameters in an entity class

6.3.3. Conventions for name, type, and size

6.3.4. By Convention, the nullability of a property is based on .NET type

6.3.5. An EF Core naming convention identifies primary keys

6.4. Configuring via Data Annotations

6.4.1. System.ComponentModel.DataAnnotations

6.4.2. System.ComponentModel.DataAnnotations.Schema

6.5. Configuring via the Fluent API

6.5.1. A better way to structure your Fluent API commands

6.6. Excluding properties and classes from the database

6.6.1. Excluding a class or property via Data Annotations

6.6.2. Excluding a class or property via the Fluent API

6.7. Configuring model-level query filters

6.8. Setting database column type, size, and nullability

6.9. The different ways of configuring the primary key

6.9.1. Configuring a primary key via Data Annotations

6.9.2. Configuring a primary key via the Fluent API

6.10. Adding indexes to database columns

6.11. Configuring the naming on the database side

6.11.1. Configuring table names

6.11.2. Configuring the schema name, and schema groupings

6.11.3. Configuring the database column names in a table

6.12. Using specific database-provider Fluent API commands

6.13. Recommendations for using EF Core’s configuration

6.13.1. Use By Convention configuration first—​its quick and easy

6.13.2. Use validation Data Annotations wherever possible

6.13.3. Use the Fluent API for anything else

6.14. Shadow properties—​hide column data inside EF Core

6.14.1. Configuring shadow properties

6.14.2. Accessing shadow properties

6.15. Backing fields—​controlling access to data in an entity class

6.15.1. Creating a simple backing field accessed by a read/write property

6.15.2. Configuring backing fields

7. Configuring relationships

7.1. Defining some relationship terms

7.2. What navigational properties do you need?

7.3. Configuring relationships

7.4. Configuring relationships By Convention

7.4.1. What makes a class an entity class?

7.4.2. An example of an entity class with navigational properties

7.4.3. How EF Core finds foreign keys By Convention

7.4.4. Nullability of foreign keys—​required or optional relationships

7.4.5. Foreign keys—​what happens if you leave them out?

7.4.6. When does By Convention configuration not work?

7.5. Configuring relationships by using Data Annotations

7.5.1. The ForeignKey Data Annotation

7.5.2. The InverseProperty Data Annotation

7.6. Fluent API relationship configuration commands

7.6.1. Creating a one-to-one relationship

7.6.2. Creating a one-to-many relationship

7.6.3. Creating a many-to-many relationship

7.7. Additional methods available in Fluent API relationships

7.7.1. OnDelete—​changing the delete action of a dependent entity

7.7.2. IsRequired—​defining the nullability of the foreign key

7.7.3. HasPrincipalKey—​using an alternate unique key

7.7.4. Less-used options in Fluent API relationships

7.8. Alternative ways of mapping entities to database tables

7.8.1. Owned types—​adding a normal class into an entity class

7.8.2. Table per hierarchy—​placing inherited classes into one table

7.8.3. Table splitting—​mapping multiple entity classes to the same table

8. Configuring advanced features and handling concurrency conflicts

8.1. Advanced feature—​using backing fields with relationships

8.1.1. The problem—​the book app performance is too slow

8.1.2. Our solution—​IEnumerable<Review> property and a backing field

8.2. DbFunction—​using user-defined functions with EF Core

8.2.1. Configuring a scalar user-defined function

8.2.2. Adding your UDF code to the database

8.2.3. Using a registered scalar UDF in your database queries

8.3. Computed column—​a dynamically calculated column value

8.4. Setting a default value for a database column

8.4.1. Adding a constant as a default constraint

8.4.2. Adding an SQL fragment as a default constraint

8.4.3. Creating a value generator to generate a default value dynamically

8.5. Sequences—​providing numbers in a strict order

8.6. Marking database-generated properties

8.6.1. Marking a column that’s generated on an addition or update

8.6.2. Marking a column’s value as set on insert of a new row

8.6.3. Marking a column as “normal”

8.7. Handling simultaneous updates—​concurrency conflicts

8.7.1. Why do concurrency conflicts matter?

8.7.2. EF Core’s concurrency conflict—​handling features

8.7.3. Handling a DbUpdateConcurrencyException

8.7.4. The disconnected concurrent update issue

9. Going deeper into the DbContext

9.1. Overview of the DbContext class’s properties

9.2. Understanding how EF Core tracks changes

9.3. Details on every command that changes an entity’s State

9.3.1. The Add command—​inserting a new row in the database

9.3.2. The Remove command—​deleting a row from the database

9.3.3. Modifying a tracked entity—​EF Core’s DetectChanges

9.3.4. INotifyPropertyChanged entities—​a different way of tracking changes

9.3.5. The Update method—​telling EF Core that everything has changed

9.3.6. The Attach method—​changing an untracked entity into a tracked entity

9.3.7. Setting the State of an entity directly

9.3.8. TrackGraph—​handling disconnected updates with relationships

9.4. Using ChangeTracker to detect changes

9.5. Using raw SQL commands in EF Core

9.5.1. FromSql—​adding raw SQL to an EF Core query

9.5.2. ExecuteSqlCommand—​executing a nonquery command

9.5.3. Reload—​useful after an ExecuteSqlCommand

9.5.4. GetDbConnection—​calling database access commands

9.6. Using Context.Model to access EF Core’s view of the database

9.6.1. Using the Model property to build a fast database wipe method

9.7. Handling database connection problems

9.7.1. Handling database transactions with EF Core’s execution strategy

9.7.2. Altering or writing your own execution strategy

Part 3: Using Entity Framework Core in real-world applications

10. Useful software patterns for EF Core applications

10.1. Another look at the separation-of-concerns principle

10.2. Using patterns to speed development of database access

10.3. Speed up query development—​use a LINQ mapper

10.4. Domain-driven-design database repository

10.4.1. Example Book DDD entity and repository

10.4.2. How the DDD design changes the business logic design

10.4.3. Impressions from building this DDD design

10.5. Is the Repository pattern useful with Entity Framework?

10.5.1. Some forms of Repository patterns to avoid

10.6. Splitting a database across multiple DbContexts

10.6.1. Creating DbContexts that contain only a subset of entities/tables

10.6.2. Passing data between bounded contexts

10.7. Data validation and error-handling patterns

10.7.1. Data validation to your entity classes makes for better error feedback

10.7.2. Business logic should contain checks and return a list of all errors

10.7.3. Catching database server errors and providing user-friendly feedback

11. Handling database migrations

11.1. Part 1—​EF Core methods to change the database schema

11.1.1. A view of what databases need updating

11.2. Code-first: using EF Core’s migrations

11.2.1. Stage 1: creating a migration—​building the code for migration

11.2.2. Stage 2: applying migrations—​updating a database schema

11.2.3. Undoing a migration—​Remove-Migration or update command

11.3. Database-first: creating a DbContext from a database

11.3.1. How to alter or edit the output from the scaffold command

11.3.2. The limitations of the reverse-engineering feature

11.4. SQL-first: using SQL change scripts to change the schema

11.4.1. Using an SQL comparison tool to build an SQL change script

11.4.2. Using EfSchemaCompare to check your SQL matches EF Core’s model

11.5. Part 2—​Issues around a database schema change

11.5.1. Applying nonbreaking changes while the current app is running

11.5.2. Applying breaking database changes by stopping the application

11.5.3. Handling breaking database changes when you can’t stop the app

12. EF Core performance tuning

12.1. Part 1—​Deciding which performance issues to fix

12.1.1. “Don’t performance tune too early” doesn’t mean you stop thinking

12.1.2. How do you decide what’s slow and needs performance tuning?

12.1.3. The cost of finding and fixing performance issues

12.2. Part 2—​Techniques for diagnosing a performance issue

12.2.1. Stage 1: get a good overview—​measuring the user’s experience

12.2.2. Stage 2: find all the database code involved in the feature you’re tuning

12.2.3. Stage 3: inspecting the SQL code to find poor performance

12.2.4. Techniques for finding database scalability issues

12.3. Part 3—​Techniques for fixing performance issues

12.4. Using good patterns makes your application perform well

12.4.1. Using Select loading to load only the columns you need

12.4.2. Using paging and/or filtering of searches to reduce the rows you load

12.4.3. A warning that using lazy loading will affect database performance

12.4.4. Always adding the AsNoTracking method to read-only queries

12.4.5. Using the async version of EF Core commands to improve scalability

12.4.6. Ensuring that your database access code is isolated/decoupled

12.5. Performance antipatterns—​database access

12.5.1. Not minimizing the number of calls to the database

12.5.2. Calling SaveChanges multiple times

12.5.3. Allowing too much of a data query to be moved into the software side

12.5.4. Not replacing suboptimal SQL translations with user-defined functions

12.5.5. Not precompiling queries that are used frequently

12.5.6. Expecting EF Core to build the best SQL database commands

12.5.7. Not using the Find method when an entity might be already loaded

12.5.8. Missing indexes from a property that you want to search on

12.5.9. Mismatching column data types

12.6. Performance antipatterns—​software

12.6.1. Making DetectChanges work too hard

12.6.2. Startup issue: using one large DbContext

12.7. Performance patterns—​scalability of database accesses

12.7.1. Using pooling to reduce the cost of a new application’s DbContext

12.7.2. Async/await—​adding scalability, with small effect on speed

12.7.3. Helping your database scalability by making your queries simple

12.7.4. Picking the right architecture for applications that need high scalability

13. A worked example of performance tuning

13.1. Part 1a—​Making sure a single query performs well

13.1.1. Analyzing the book list query to see potential performance issues

13.1.2. Turning the book’s Votes display into a client-side calculation

13.2. Part 1b—​Improving the query by adding a DbFunction

13.2.1. Looking at the updated query

13.2.2. Ensuring that the query sorting and filtering are performing well

13.3. Part 2—​Converting EF Core commands to SQL queries

13.3.1. Introducing Dapper

13.3.2. Rewriting MapBookToDto and associated EF queries using Dapper

13.4. Part 3—​Modifying the database to increase performance

13.4.1. Creating an ActualPrice property—​changing the promotion process

13.4.2. Caching the book review values, and not letting them get out-of-date

13.4.3. Calculating AuthorsString when a book is first created

13.4.4. Analyzing the changes—​Is the performance gain worth the effort?

13.5. Comparing parts 1a, 1b, 2, and 3

13.6. Database scalability—​what can you do to improve that?

14. Different database types and EF Core services

14.1. What differences do other database server types bring?

14.1.1. Creating an instance of the application’s DbContext for MySQL

14.1.2. What you have to do to convert the SQL Server application to MySQL

14.1.3. Looking at other database server types and differences

14.1.4. Summarizing EF Core’s ability to work with multiple database types

14.2. Developing a CQRS architecture application with EF Core

14.2.1. Implementation of a two-database CQRS architecture application

14.2.2. How the parts of the CQRS solution interact with each other

14.2.3. Finding book view changes—​Part 1, finding the correct state and key

14.2.4. Finding the book view changes—​Part 2, building the correct State

14.2.5. Why the CQRS solution is less likely to have out-of-date cached values

14.2.6. Is the two-database CQRS architecture worth the effort?

14.3. Accessing and changing EF Core services

14.3.1. Accessing an EF Core service to help in your own application

14.3.2. Replacing an EF Core service with your own modified service

14.4. Accessing command-line tools from software

14.4.1. How to access EF Core design-time services

14.4.2. How to use design-time services to build the EfSchemaCompare tool

15. Unit testing EF Core applications

15.1. Introduction—​our unit test setup

15.1.1. The test environment—​the xUnit unit test library

15.1.2. A library I’ve created to help with unit testing EF Core applications

15.2. Simulating the database when testing EF Core

15.3. applications

15.3.1. The options you have for simulating the database

15.3.2. Choosing between an in-memory or real database for unit testing

15.4. Getting your application’s DbContext ready for unit testing

15.4.1. The application’s DbContext options are provided via its constructor

15.4.2. Setting an application’s DbContext options via OnConfiguring

15.5. Simulating a database—​using an in-memory database

15.6. Using a real database in your unit tests

15.6.1. How to set up a real database for unit testing

15.6.2. Running unit tests in parallel—​uniquely named databases

15.6.3. Tips on how to speed up the database creation stage of a unit test

15.6.4. How to handle databases in which you’ve added extra SQL code

15.7. Unit testing a disconnected state update properly

15.8. Mocking a database repository pattern

15.9. Capturing EF Core logging information in unit testing

15.9.1. Using logging to help you build SQL change scripts

15.10. Using the EfSchemaCompare tool in your unit tests

15.10.1. Features and options for the EfSchemaCompare tool

Appendixes

Appendix A: A brief introduction to LINQ

Appendix B: Early information on EF Core version 2.1

About the Technology

There’s a mismatch in the way OO programs and relational databases represent data. Entity Framework is an object-relational mapper (ORM) that bridges this gap, making it radically easier to query and write to databases from a .NET application. EF creates a data model that matches the structure of your OO code so you can query and write to your database using standard LINQ commands. It will even automatically generate the model from your database schema.

About the book

Using crystal-clear explanations, real-world examples, and around 100 diagrams, Entity Framework Core in Action teaches you how to access and update relational data from .NET applications. You’ll start with a clear breakdown of Entity Framework, long with the mental model behind ORM. Then you’ll discover time-saving patterns and best practices for security, performance tuning, and even unit testing. As you go, you’ll address common data access challenges and learn how to handle them with Entity Framework.

What's inside

  • Querying a relational database with LINQ
  • Using EF Core in business logic
  • Integrating EF with existing C# applications
  • Applying domain-driven design to EF Core
  • Getting the best performance out of EF Core
  • Covers EF Core 2.0 and 2.1

About the reader

For .NET developers with some awareness of how relational databases work.

About the author

Jon P Smith is a full-stack developer with special focus on .NET Core and Azure.


buy
Entity Framework Core in Action (combo) added to cart
continue shopping
go to cart

combo $49.99 pBook + eBook + liveBook
eBook $39.99 pdf + ePub + kindle + liveBook

FREE domestic shipping on three or more pBooks

A solid book that deals well with the topic at hand, but also handles the wider concerns around using EF in real-world applications.

Sebastian Rogers, Simple Innovations

This is the next step beyond the basics. It’ll help you get to the next level!

Jeff Smith, Agilify Automation

Great book with excellent, real-world examples.

Tanya Wilke, Sanlam