Allow entity instances to be tracked by two bounded contexts, but limit updates to one context

Open
#23,457 9 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Stale
Tech stack
csharp
Domain
database

Research direction

Review the DbContext model configuration, entity tracking, the documented migration-exclusion API, and the per-query AsNoTracking approach. Done would be a supported model-level way for DbContext B to read and join User without tracking or inserting it, while DbContext A retains create, update, and delete responsibility.

Written by the indexing model from the issue text.

Description

area-change-tracking customer-reported

Ask a question

I am using bounded contexts.
This means I have two different DbContexts, with their own entities, and own "Schema", but sharing the same connection string.

My question comes where there is a relationship between the boundaries.
In DbContext A there is a User Entity.
In DbContext B there is a need to "join" some Foo entity to the User entity - so I want to model this as a navigation property (from Foo --> User).

I have found that I can include the User entity into the model for DbContext B - and ignore it for migration purposes as documented here:
https://docs.microsoft.com/en-us/ef/core/modeling/entity-types?tabs=data-annotations#excluding-from-migrations

However, I want to make it explicit that this User entity should only be tracked in DbContext A, and not tracked in DbContext B. This is because responsibility for the Create, Update and Delete of the User entity should only ever be performed in DbContext A. DbContext B just needs the ability to read and join to this entity in it's model.

I have seen from here: https://stackoverflow.com/questions/9415334/entity-framework-code-first-readonly-entity that you can use AsNoTracking() on a per query level to do this. However is there anything I can do at the model level - similar to the exclude migration api I linked above, that tells DbContext B to never track this entity.

The issue I am trying to avoid is this:

  1. In my application I use some service that creates and adds a User entity to DbContext A.
  2. I then use another service that creates a Foo entity in DbContext B, and sets a navigation property on the Foo entity, to the User entity thats already been added to DbContext A, and was not tracked previously by DbContext B.
  3. I call SaveChanges() on DbContext A which inserts the User entity.
  4. I call SaveChanges() on DbContext B, which, sees the navigation property on the Foo entity to the User entity - and also tries to insert a new User entity.

Note: I haven't actually tested this scenario yet but I am assuming this problem would occur based on my current understanding of EF Core and how it wants to track entities. Between steps 3 and 4, the User entity will have been inserted but DbContext B will not know that - despite the User entity has now been assigned an Id by DbContext A after the insert.

Rather than addressing this on a per-query basis, I'd like to know if there is something I can do at a model level so better isolate entities to prevent them from being tracked in contexts that should not "own" them.

Include provider and version information

EF Core version: 5.0.0
Database provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer): Microsoft.EntityFrameworkCore.SqlServer
Target framework: (e.g. .NET 5.0): .NET 5.0
Operating system: Windows 10
IDE: (e.g. Visual Studio 2019 16.3): Visual Studio 2019 Pro 16.8.2

Dominant language
C#
Stars
14.8k
Forks
3.4k
Avg merge
2d 5h
Merged PRs (30d)
134

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/efcore

All issues in dotnet/efcore

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.