Entity Framework Core in Action

Book description

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.

Table of contents

  1. Titlepage
  2. Copyright
  3. preface
  4. acknowledgments
  5. about this book
    1. Who should read this book
    2. How this book is organized
    3. About the code
    4. Code conventions
    5. Book forum
    6. Online resources
  6. about the author
  7. about the cover illustration
  8. Part 1: Getting started
    1. Chapter 1: Introduction to Entity FrameworkCore
      1. 1.1 What you’ll learn from this book
      2. 1.2 My “lightbulb moment” with Entity Framework
      3. 1.3 Some words for existing EF6.x developers
      4. 1.4 An overview of EF Core
        1. 1.4.1 The downsides of O/RMs
      5. 1.5 What about NoSQL?
      6. 1.6 Your first EF Core application
        1. 1.6.1 What you need to install
        2. 1.6.2 Creating your own .NET Core console app with EF Core
      7. 1.7 The database that MyFirstEfCoreApp will access
      8. 1.8 Setting up the MyFirstEfCoreApp application
        1. The classes that map to the database—Book and Author
        2. 1.8.2 The application’s DbContext
      9. 1.9 Looking under the hood of EF Core
        1. 1.9.1 Modeling the database
        2. 1.9.2 Reading data from the database
        3. 1.9.3 Updating the database
      10. 1.10 Should you use EF Core in your next project?
        1. 1.10.1 Latest generation
        2. 1.10.2 Multiplatform and open source
        3. 1.10.3 Rapid development
        4. 1.10.4 Well supported
        5. 1.10.5 Access to NuGet libraries
        6. 1.10.6 Fully featured O/RM
        7. 1.10.7 Stable library
        8. 1.10.8 Always high-performance
      11. 1.11 When should you not use EF Core?
      12. Summary
    2. Chapter 2: Querying the database
      1. 2.1 Setting the scene—our book-selling site
        1. 2.1.1 The book app’s relational database
        2. 2.1.2 Other relationship types not covered in this chapter
        3. 2.1.3 The final database showing all the tables
        4. 2.1.4 The classes that EF Core maps to the database
      2. 2.2 Creating the application’s DbContext
        1. 2.2.1 Defining the application’s DbContext: EfCoreContext
        2. 2.2.2 Creating an instance of the application’s DbContext
        3. 2.2.3 Creating a database for your own application
      3. 2.3 Understanding database queries
        1. 2.3.1 Application’s DbContext property access
        2. 2.3.2 A series of LINQ/EF Core commands
        3. 2.3.3 The execute command
      4. 2.4 Loading related data
        1. 2.4.1 Eager loading: loading relationships with the primary entity class
        2. 2.4.2 Explicit loading: loading relationships after the primary entity class
        3. 2.4.3 Select loading: loading specific parts of primary entity class and any relationships
      5. 2.5 Using client vs. server evaluation: moving part of your query into software
        1. 2.5.1 Creating the display string of a book’s authors
        2. 2.5.2 Understanding the limitations of client vs. server evaluation
      6. 2.6 Building complex queries
        1. 2.6.1 Building the book list query by using select loading
        2. 2.6.2 Introducing the architecture of the book app
      7. 2.7 Adding sorting, filtering, and paging
        1. 2.7.1 Sorting books by price, publication date, and customer ratings
        2. 2.7.2 Filtering books by publication year and customer ratings
        3. 2.7.3 Paging the books in the list
      8. 2.8 Putting it all together: combining query objects
      9. Summary
    3. Chapter 3: Changing the database content
      1. 3.1 Introducing EF Core’s entity State
      2. 3.2 Creating new rows in a table
        1. 3.2.1 Creating a single entity on its own
        2. 3.2.2 Creating a book with a review
      3. 3.3 Updating database rows
        1. 3.3.1 Handling disconnected updates in a web application
      4. 3.4 Handling relationships in updates
        1. 3.4.1 Principal and dependent relationships
        2. 3.4.2 Updating one-to-one relationships—adding a PriceOffer to a book
        3. 3.4.3 Updating one-to-many relationships—adding a review to a book
        4. 3.4.4 Updating many-to-many relationships—changing a book’s authors
        5. 3.4.5 Advanced feature—updating relationships via foreign keys
      5. 3.5 Deleting entities
        1. 3.5.1 Using a soft delete—using model-level query filters to “hide” entities
        2. 3.5.2 Deleting a dependent-only entity—no relationships
        3. 3.5.3 Deleting a principal entity that has relationships
      6. Summary
    4. Chapter 4: Using EF Core in business logic
      1. 4.1 Why is business logic so different from other code?
      2. 4.2 Our business need—processing an order for books
        1. 4.2.1 The business rules that you need to implement
      3. 4.3 Using a design pattern to help implement business logic
        1. 4.3.1 Five guidelines for building business logic that uses EF Core
      4. 4.4 Implementing the business logic for processing an order
        1. 4.4.1 Guideline 1: Business logic has first call on defining the database structure
        2. 4.4.2 Guideline 2: Business logic should have no distractions
        3. 4.4.3 Guideline 3: Business logic should think it’s working on in-memory data
        4. 4.4.4 Guideline 4: Isolate the database access code into a separate project
        5. 4.4.5 Guideline 5: Business logic shouldn’t call EF Core’s SaveChanges
        6. 4.4.6 Putting it all together—calling the order-processing business logic
        7. 4.4.7 Any disadvantages of this business logic pattern?
      5. 4.5 Placing an order on the book app
      6. 4.6 Adding extra features to your business logic handling
        1. 4.6.1 Validating the data that you write to the database
        2. 4.6.2 Using transactions to daisy-chain a sequence of business logic code
      7. Summary
    5. Chapter 5: Using EF Core in ASP.NET Core web applications
      1. 5.1 Introducing ASP.NET Core
      2. 5.2 Understanding the architecture of the book app
      3. 5.3 Understanding dependency injection
        1. 5.3.1 Why you need to learn about DI in ASP.NET Core
        2. 5.3.2 A basic example of dependency injection in ASP.NET Core
        3. 5.3.3 The lifetime of a service created by DI
      4. 5.4 Making the application’s DbContext available via DI
        1. 5.4.1 Providing information on the database’s location
        2. 5.4.2 Registering your application’s DbContext with the DI provider
      5. 5.5 Calling your database access code from ASP.NET Core
        1. 5.5.1 A summary of how ASP.NET Core works and the terms it uses
        2. 5.5.2 Where does the EF Core code live in the book app?
      6. 5.6 Implementing the book list query page
      7. 5.7 Implementing your database methods as a DI service
        1. 5.7.1 Registering your class as a DI service
        2. 5.7.2 Injecting ChangePubDateService into the ASP.NET action method
        3. 5.7.3 Improving registering your database access classes as services
      8. 5.8 Deploying an ASP.NET Core application with a database
        1. 5.8.1 Knowing where the database is on the web server
        2. 5.8.2 Creating and migrating the database
      9. 5.9 Using EF Core’s Migrate to change the database structure
        1. 5.9.1 Updating your production database
        2. 5.9.2 Having your application migrate your database on startup
      10. 5.10 Using async/await for better scalability
        1. 5.10.1 Why async/await is useful in a web application using EF Core
        2. 5.10.2 Where should you use async/await with database accesses?
        3. 5.10.3 Changing over to async/await versions of EF Core commands
      11. 5.11 Running parallel tasks: how to provide the DbContext
        1. 5.11.1 Other ways of obtaining a new instance of the application’s DbContext
      12. Summary
  9. Part 2: Entity Framework in depth
    1. Chapter 6: Configuring nonrelational properties
      1. 6.1 Three ways of configuring EF Core
      2. 6.2 A worked example of configuring EF Core
      3. 6.3 Configuring By Convention
        1. 6.3.1 Conventions for entity classes
        2. 6.3.2 Conventions for parameters in an entity class
        3. 6.3.3 Conventions for name, type, and size
        4. 6.3.4 By Convention, the nullability of a property is based on .NET type
        5. 6.3.5 An EF Core naming convention identifies primary keys
      4. 6.4 Configuring via Data Annotations
        1. 6.4.1 System.ComponentModel.DataAnnotations
        2. 6.4.2 System.ComponentModel.DataAnnotations.Schema
      5. 6.5 Configuring via the Fluent API
        1. 6.5.1 A better way to structure your Fluent API commands
      6. 6.6 Excluding properties and classes from the database
        1. 6.6.1 Excluding a class or property via Data Annotations
        2. 6.6.2 Excluding a class or property via the Fluent API
      7. 6.7 Configuring model-level query filters
      8. 6.8 Setting database column type, size, and nullability
      9. 6.9 The different ways of configuring the primary key
        1. 6.9.1 Configuring a primary key via Data Annotations
        2. 6.9.2 Configuring a primary key via the Fluent API
      10. 6.10 Adding indexes to database columns
      11. 6.11 Configuring the naming on the database side
        1. 6.11.1 Configuring table names
        2. 6.11.2 Configuring the schema name, and schema groupings
        3. 6.11.3 Configuring the database column names in a table
      12. 6.12 Using specific database-provider Fluent API commands
      13. 6.13 Recommendations for using EF Core’s configuration
        1. 6.13.1 Use By Convention configuration first—its quick and easy
        2. 6.13.2 Use validation Data Annotations wherever possible
        3. 6.13.3 Use the Fluent API for anything else
      14. 6.14 Shadow properties—hide column data inside EF Core
        1. 6.14.1 Configuring shadow properties
        2. 6.14.2 Accessing shadow properties
      15. 6.15 Backing fields—controlling access to data in an entity class
        1. 6.15.1 Creating a simple backing field accessed by a read/write property
        2. 6.15.2 Configuring backing fields
      16. Summary
    2. Chapter 7: Configuring relationships
      1. 7.1 Defining some relationship terms
      2. 7.2 What navigational properties do you need?
      3. 7.3 Configuring relationships
      4. 7.4 Configuring relationships By Convention
        1. 7.4.1 What makes a class an entity class?
        2. 7.4.2 An example of an entity class with navigational properties
        3. 7.4.3 How EF Core finds foreign keys By Convention
        4. 7.4.4 Nullability of foreign keys—required or optional relationships
        5. 7.4.5 Foreign keys—what happens if you leave them out?
        6. 7.4.6 When does By Convention configuration not work?
      5. 7.5 Configuring relationships by using Data Annotations
        1. 7.5.1 The ForeignKey Data Annotation
        2. 7.5.2 The InverseProperty Data Annotation
      6. 7.6 Fluent API relationship configuration commands
        1. 7.6.1 Creating a one-to-one relationship
        2. 7.6.2 Creating a one-to-many relationship
        3. 7.6.3 Creating a many-to-many relationship
      7. 7.7 Additional methods available in Fluent API relationships
        1. 7.7.1 OnDelete—changing the delete action of a dependent entity
        2. 7.7.2 IsRequired—defining the nullability of the foreign key
        3. 7.7.3 HasPrincipalKey—using an alternate unique key
        4. 7.7.4 Less-used options in Fluent API relationships
      8. 7.8 Alternative ways of mapping entities to database tables
        1. 7.8.1 Owned types—adding a normal class into an entity class
        2. 7.8.2 Table per hierarchy—placing inherited classes into one table
        3. 7.8.3 Table splitting—mapping multiple entity classes to the same table
      9. Summary
    3. Chapter 8: Configuring advanced features and handling concurrency conflicts
      1. 8.1 Advanced feature—using backing fields with relationships
        1. 8.1.1 The problem—the book app performance is too slow
        2. 8.1.2 Our solution—IEnumerable<Review> property and a backing field
      2. 8.2 DbFunction—using user-defined functions with EF Core
        1. 8.2.1 Configuring a scalar user-defined function
        2. 8.2.2 Adding your UDF code to the database
        3. 8.2.3 Using a registered scalar UDF in your database queries
      3. 8.3 Computed column—a dynamically calculated column value
      4. 8.4 Setting a default value for a database column
        1. 8.4.1 Adding a constant as a default constraint
        2. 8.4.2 Adding an SQL fragment as a default constraint
        3. 8.4.3 Creating a value generator to generate a default value dynamically
      5. 8.5 Sequences—providing numbers in a strict order
      6. 8.6 Marking database-generated properties
        1. 8.6.1 Marking a column that’s generated on an addition or update
        2. 8.6.2 Marking a column’s value as set on insert of a new row
        3. 8.6.3 Marking a column as “normal”
      7. 8.7 Handling simultaneous updates—concurrency conflicts
        1. 8.7.1 Why do concurrency conflicts matter?
        2. 8.7.2 EF Core’s concurrency conflict–handling features
        3. 8.7.3 Handling a DbUpdateConcurrencyException
        4. 8.7.4 The disconnected concurrent update issue
      8. Summary
    4. Chapter 9: Going deeper into the DbContext
      1. 9.1 Overview of the DbContext class’s properties
      2. 9.2 Understanding how EF Core tracks changes
      3. 9.3 Details on every command that changes an entity’s State
        1. 9.3.1 The Add command--inserting a new row in the database
        2. 9.3.2 The Remove command—deleting a row from the database
        3. 9.3.3 Modifying a tracked entity—EF Core’s DetectChanges
        4. 9.3.4 INotifyPropertyChanged entities—a different way of tracking changes
        5. 9.3.5 The Update method—telling EF Core that everything has changed
        6. 9.3.6 The Attach method—changing an untracked entity into a tracked entity
        7. 9.3.7 Setting the State of an entity directly
        8. 9.3.8 TrackGraph—handling disconnected updates with relationships
      4. 9.4 Using ChangeTracker to detect changes
      5. 9.5 Using raw SQL commands in EF Core
        1. 9.5.1 FromSql—adding raw SQL to an EF Core query
        2. 9.5.2 ExecuteSqlCommand—executing a nonquery command
        3. 9.5.3 Reload—useful after an ExecuteSqlCommand
        4. 9.5.4 GetDbConnection—calling database access commands
      6. 9.6 Using Context.Model to access EF Core’s view of the database
        1. 9.6.1 Using the Model property to build a fast database wipe method
      7. 9.7 Handling database connection problems
        1. 9.7.1 Handling database transactions with EF Core’s execution strategy
        2. 9.7.2 Altering or writing your own execution strategy
      8. Summary
  10. Part 3: Using Entity Framework Core in real-world applications
    1. Chapter 10: Useful software patterns for EF Core applications
      1. 10.1 Another look at the separation-of-concerns principle
      2. 10.2 Using patterns to speed development of database access
      3. 10.3 Speed up query development—use a LINQ mapper
      4. 10.4 Domain-driven-design database repository
        1. 10.4.1 Example Book DDD entity and repository
        2. 10.4.2 How the DDD design changes the business logic design
        3. 10.4.3 Impressions from building this DDD design
      5. 10.5 Is the Repository pattern useful with Entity Framework?
        1. 10.5.1 Some forms of Repository patterns to avoid
      6. 10.6 Splitting a database across multiple DbContexts
        1. 10.6.1 Creating DbContexts that contain only a subset of entities/tables
        2. 10.6.2 Passing data between bounded contexts
      7. 10.7 Data validation and error-handling patterns
        1. 10.7.1 Data validation to your entity classes makes for better error feedback
        2. 10.7.2 Business logic should contain checks and return a list of all errors
        3. 10.7.3 Catching database server errors and providing user-friendly feedback
      8. Summary
    2. Chapter 11: Handling database migrations
      1. 11.1 Part 1—EF Core methods to change the database schema
        1. 11.1.1 A view of what databases need updating
      2. 11.2 Code-first: using EF Core’s migrations
        1. 11.2.1 Stage 1: creating a migration—building the code for migration
        2. 11.2.2 Stage 2: applying migrations—updating a database schema
        3. 11.2.3 Undoing a migration—Remove-Migration or update command
      3. 11.3 Database-first: creating a DbContext from a database
        1. 11.3.1 How to alter or edit the output from the scaffold command
        2. 11.3.2 The limitations of the reverse-engineering feature
      4. 11.4 SQL-first: using SQL change scripts to change the schema
        1. 11.4.1 Using an SQL comparison tool to build an SQL change script
        2. 11.4.2 Using EfSchemaCompare to check your SQL matches EF Core’s model
      5. 11.5 Part 2—Issues around a database schema change
        1. 11.5.1 Applying nonbreaking changes while the current app is running
        2. 11.5.2 Applying breaking database changes by stopping the application
        3. 11.5.3 Handling breaking database changes when you can’t stop the app
      6. Summary
    3. Chapter 12: EF Core performance tuning
      1. 12.1 Part 1—Deciding which performance issues to fix
        1. 12.1.1 “Don’t performance tune too early” doesn’t mean you stop thinking
        2. 12.1.2 How do you decide what’s slow and needs performance tuning?
        3. 12.1.3 The cost of finding and fixing performance issues
      2. 12.2 Part 2—Techniques for diagnosing a performance issue
        1. 12.2.1 Stage 1: get a good overview—measuring the user’s experience
        2. 12.2.2 Stage 2: find all the database code involved in the feature you’re tuning
        3. 12.2.3 Stage 3: inspecting the SQL code to find poor performance
        4. 12.2.4 Techniques for finding database scalability issues
      3. 12.3 Part 3—Techniques for fixing performance issues
      4. 12.4 Using good patterns makes your application perform well
        1. 12.4.1 Using Select loading to load only the columns you need
        2. 12.4.2 Using paging and/or filtering of searches to reduce the rows you load
        3. 12.4.3 A warning that using lazy loading will affect database performance
        4. 12.4.4 Always adding the AsNoTracking method to read-only queries
        5. 12.4.5 Using the async version of EF Core commands to improve scalability
        6. 12.4.6 Ensuring that your database access code is isolated/decoupled
      5. 12.5 Performance antipatterns—database access
        1. 12.5.1 Not minimizing the number of calls to the database
        2. 12.5.2 Calling SaveChanges multiple times
        3. 12.5.3 Allowing too much of a data query to be moved into the software side
        4. 12.5.4 Not replacing suboptimal SQL translations with user-defined functions
        5. 12.5.5 Not precompiling queries that are used frequently
        6. 12.5.6 Expecting EF Core to build the best SQL database commands
        7. 12.5.7 Not using the Find method when an entity might be already loaded
        8. 12.5.8 Missing indexes from a property that you want to search on
        9. 12.5.9 Mismatching column data types
      6. 12.6 Performance antipatterns—software
        1. 12.6.1 Making DetectChanges work too hard
        2. 12.6.2 Startup issue: using one large DbContext
      7. 12.7 Performance patterns—scalability of database accesses
        1. 12.7.1 Using pooling to reduce the cost of a new application’s DbContext
        2. 12.7.2 Async/await—adding scalability, with small effect on speed
        3. 12.7.3 Helping your database scalability by making your queries simple
        4. 12.7.4 Picking the right architecture for applications that need high scalability
      8. Summary
    4. Chapter 13: A worked example of performance tuning
      1. 13.1 Part 1a—Making sure a single query performs well
        1. 13.1.1 Analyzing the book list query to see potential performance issues
        2. 13.1.2 Turning the book’s Votes display into a client-side calculation
      2. 13.2 Part 1b—Improving the query by adding a DbFunction
        1. 13.2.1 Looking at the updated query
        2. 13.2.2 Ensuring that the query sorting and filtering are performing well
      3. 13.3 Part 2—Converting EF Core commands to SQL queries
        1. 13.3.1 Introducing Dapper
        2. 13.3.2 Rewriting MapBookToDto and associated EF queries using Dapper
      4. 13.4 Part 3—Modifying the database to increase performance
        1. 13.4.1 Creating an ActualPrice property—changing the promotion process
        2. 13.4.2 Caching the book review values, and not letting them get out-of-date
        3. 13.4.3 Calculating AuthorsString when a book is first created
        4. 13.4.4 Analyzing the changes—Is the performance gain worth the effort?
      5. 13.5 Comparing parts 1a, 1b, 2, and 3
      6. 13.6 Database scalability—what can you do to improve that?
      7. Summary
    5. Chapter 14: Different database types and EF Core services
      1. 14.1 What differences do other database server types bring?
        1. 14.1.1 Creating an instance of the application’s DbContext for MySQL
        2. 14.1.2 What you have to do to convert the SQL Server application to MySQL
        3. 14.1.3 Looking at other database server types and differences
        4. 14.1.4 Summarizing EF Core’s ability to work with multiple database types
      2. 14.2 Developing a CQRS architecture application with EF Core
        1. 14.2.1 Implementation of a two-database CQRS architecture application
        2. 14.2.2 How the parts of the CQRS solution interact with each other
        3. 14.2.3 Finding book view changes—Part 1, finding the correct state and key
        4. 14.2.4 Finding the book view changes—Part 2, building the correct State
        5. 14.2.5 Why the CQRS solution is less likely to have out-of-date cached values
        6. 14.2.6 Is the two-database CQRS architecture worth the effort?
      3. 14.3 Accessing and changing EF Core services
        1. 14.3.1 Accessing an EF Core service to help in your own application
        2. 14.3.2 Replacing an EF Core service with your own modified service
      4. 14.4 Accessing command-line tools from software
        1. 14.4.1 How to access EF Core design-time services
        2. 14.4.2 How to use design-time services to build the EfSchemaCompare tool
      5. Summary
    6. Chapter 15: Unit testing EF Core applications
      1. 15.1 Introduction—our unit test setup
        1. 15.1.1 The test environment—the xUnit unit test library
        2. 15.1.2 A library I’ve created to help with unit testing EF Core applications
    7. 15.2 Simulating the database when testing EF Core applications
      1. 15.2.1 The options you have for simulating the database
      2. 15.2.2 Choosing between an in-memory or real database for unit testing
    8. 15.3 Getting your application’s DbContext ready for unit testing
      1. 15.3.1 The application’s DbContext options are provided via its constructor
      2. 15.3.2 Setting an application’s DbContext options via OnConfiguring
    9. 15.4 Simulating a database—using an in-memory database
    10. 15.5 Using a real database in your unit tests
      1. 15.5.1 How to set up a real database for unit testing
      2. 15.5.2 Running unit tests in parallel—uniquely named databases
      3. 15.5.3 Tips on how to speed up the database creation stage of a unit test
      4. 15.5.4 How to handle databases in which you’ve added extra SQL code
    11. 15.6 Unit testing a disconnected state update properly
    12. 15.7 Mocking a database repository pattern
    13. 15.8 Capturing EF Core logging information in unit testing
      1. 15.8.1 Using logging to help you build SQL change scripts
    14. 15.9 Using the EfSchemaCompare tool in your unit tests
      1. 15.9.1 Features and options for the EfSchemaCompare tool
    15. Summary
  11. appendix A: A brief introduction to LINQ
    1. A.1 An introduction to the LINQ language
      1. A.1.1 The two ways you can write LINQ queries
      2. A.1.2 The data operations you can do with LINQ
    2. A.2 Introduction to IQueryable<T> type, and why it’s useful
      1. A.2.1 Splitting up a complex LINQ query by using the IQueryable<T> type
      2. A.2.2 How EF Core translates IQueryable<T> into database code
    3. A.3 Querying an EF Core database by using LINQ
    4. Summary
  12. appendix B: Early information on EF Core version 2.1
    1. B.1 What does the 2.1 in the EF Core release number mean?
    2. B.2 Brand-new features
      1. B.2.1 Lazy loading—loading relationships when you need them
      2. B.2.2 Parameters in entity class constructors
      3. B.2.3 Value conversion—defining the mapping of value types to the database
      4. B.2.4 Data seeding—adding initial data to a new/updated database
      5. B.2.5 Query types—using non-entity classes in read-only queries
      6. B.2.6 Include derived types when using table per hierarchy
      7. B.2.7 Ability to link to entity class state change events
      8. B.2.8 Supporting NoSQL—Cosmos NoSQL Database provider (preview)
    3. B.3 Improvements to existing features
      1. B.3.1 LINQ GroupBy translation to SQL GROUP BY command
      2. B.3.2 Optimization of correlated subqueries—the N + 1 SQL query problem
      3. B.3.3 .NET Core global tools—installing design-time tools locally
      4. B.3.4 Column ordering in database now follows entity-class property order
      5. B.3.5 System.Transactions support
      6. B.3.6 Specifying an owned type via an attribute
    4. Summary
  13. Index

Product information

  • Title: Entity Framework Core in Action
  • Author(s): Jon Smith
  • Release date: August 2018
  • Publisher(s): Manning Publications
  • ISBN: 9781617294563