Giter Site home page Giter Site logo

efcorestatetest's Introduction

Entity Framework Core State Tests

This project has a bunch of tests that show how EF Core state works.

The Code

The project is was created using the .NET Core NUnit template, then added the Microsoft.EntityFrameworkCore.SqlServer and Shouldly packages. It only consists of unit tests that test the various ways EF Core core changes the state of objects. I used VS Code on Windows for development. There is also a sln file for use in Visual Studio 2019. Its Live Unit Test feature works well with this project.

Like the EF Core samples, this code uses the code-first method, and a (localdb)\mssqllocaldb database server.

To run the tests simply invoke them with

dotnet test

It will output the typical test results. If you run tests from VSCode, it will also show the stdout logging that shows object states. Details about the tests follow a brief discussion of state.

EF Core Entity State

There are many good articles about EF Core (see links below). This blog will focus mainly on the State of objects and how they change within a DbContext. This section gives a brief overview of State.

The DbContext tracks the state of objects so that when SaveChanges is called, it knows what UPDATE, INSERT, or DELETE statements to generate. The possible states are as follows:

State Action on SaveChanges Notes
Added INSERT PK can have no value if generated by EF
Modified UPDATE Uses PK to update
Deleted DELETE Uses PK to delete
Unchanged None Retrieved from database, Attached, or after SaveChanges
Detached None Context is not tracking the object

Objects that the context does not know about are in the Detached state. For the context to know about an object, you either retrieve it from the database with the context or use one of the calls to get in into the context.

Method Resulting State
Add Added
Update Added if PK is not set else Modified
Find or retrieve via DbSet, etc. Unchanged
Attach Added if PK is not set else Unchanged

If EF Core knows about your PKs, Update works for both adds and updates of objects. There may be cases where the object needs to have the PK set ahead of time, so you'll need to call Add to do an add. An example is where a child table's PK is a FK to the parent.

The following diagram shows how the EF Core State changed with various DbContext methods, or other actions.

StateDiagram

Test Details

The tests cover all the paths in the diagram in at least one flavor.

The Model

A simple set of classes are used for the tests. The Thing class is just a standalone (no relationships) class for testing basic state.

The Loan class has a Lender and LenderContact to complicate things the LenderContact also has a Lender. This cyclic relationship was the impetus for writing this article so I could get a good understanding of how to solve that problem.

ChangingThingStateShould.cs

This file tests state changes for one object with no realtionships. Each of the paths in the diagram are tested.

Path Test
Detached->Added->Unchanged Construct_Update_Save_SingleObject
Construct_Add_Save_SingleObject
Construct_Attach_Save_SingleObject
Detached->Modified->Unchanged Save_Update_SingleObject
retrieve->Unchanged Save_Find_SingleObject
retrieve->Unchanged->Modified->Unchanged Save_Find_Update_SingleObject
retrieve->Unchanged->Deleted->Detached Save_Find_Delete_SingleObject
Detached->Unchanged Construct_Attach_SetState_SingleObject
Construct_SetState_SingleObject

Note, the last two explicitly set the state which is a path not shown in the diagram.

ChangingGraphStatesShould.cs

This file does the basic actions on the Loan graph of objects. When retrieving a Loan that include the Lender and LenderContact, the Lender will be in the graph twice (since LenderContact also has the same Lender).

When sending that to a server (simulated with serialization in the test) and trying to Attach() or Update() the object, EF will throw an exception saying that a Lender with the same Id is already being tracked.

Setting the State directly on the Loan avoids the recursive attaching of the other functions and then the Loan can be saved in the database. There are other ways around this, but in my case, that's what was being sent to the server. One way is to include LenderId and LenderContactId in the Loan object. The LoanEx class does that and ChangingGraphExStatesShould.cs demonstrates that.

Path Test
Detached->Added->Unchanged ConstructGraph_Attach_Save
ConstructGraph_Add_Save
ConstructGraph_Update_Save
Detached->Modified->Unchanged Save_Linq_Include_SetState_Graph
retrieve->Unchanged Save_Find_Graph
Save_Linq_Graph
Save_Linq_Include_Graph
Detached->error attaching Save_Linq_Include_Attach_Graph_Throw
Save_Linq_Include_Update_Graph_Throw
retrieve->Unchanged->Modified->Unchanged Save_Find_Update_Graph
retrieve->Unchanged->Deleted->Detached ConstructGraph_Add_Save_Delete
Detached->Unchanged ConstructGraph_Attach_SetState
ConstructGraph_SetState

Links

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.