-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow entity instances to be tracked by two bounded contexts, but limit updates to one context #23457
Comments
I don't think you're going to be able to do this if the entity is part of the graph being tracked and is needed for the correct update to be generated. If it's not needed for the update, then you could not track it, but this would have to be done manually. I wouldn't recommend trying to do this.
If you don't need the entity to be in the graph for the update, then this would work. But typically then you just wouldn't have the entity present at all.
No.
After step 3, the entity tracked by context B is no longer in sync with the state of the entity in the database. You'll need to update its state to reflect that of the database. For example, it may need to have generated key values propagated. In general, I think you're probably looking for read-only entities--the issue you referenced above. However, implementation of that issue would not result in entities not being tracked, but rather not allowing changes. In your case, you want the changes to be ignored, which is one option for read-only entities, the other being to throw if they are changed. However, it's still not clear to me how you would deal with propagating values correctly. |
Thanks.
Not sure I understand that bit!
I believe this to be true, except having to do AsNoTracking for each query rather than defining a particular entity type to be read only at a model level seems problematic for the code base and a possible source of error. Perhaps I am missing a trick. I think.. Im looking for a feature to better support this scenario with bounded contexts concisely. I feel its a requirement really, for full "bounded context" support? 1.Entities A, B, C in bounded context 1 need to "relate" to an entity D in another seperate bounded context 2. I should stop here and say - would be great to understand how the EF core team thinks this should be modelled with current EF features, in a best practice way, or if its not supported, make that explicit in the docs that talk about bounded contexts as that could be considered a deal breaking limitation for some.
Thinking you get the gist :-) |
@dazinator |
@dazinator There is definitely room to make this experience better. My gut feeling is that using read-only entities is the way to handle this, rather than through attempting not to track in one context or the other. A proper implementation of read-only entity types is tracked by #7586. I'm going to make a note on that issue to consider this scenario, and put this in the backlog to specifically track the bounded context scenario, since read-only entity types are much more general than just this. |
I'd suggest being very careful with approach. I can see the desire to incrementally move towards bounded contexts, but it's really just a facade:
Have you looked into using composition (either server-side or client-side) instead? It'd look something like this: Saving
Reading
I think you'll find this pattern will set you up much better for success. Also, if you're not already following him, Udi Dahan has some really good content around finding service boundaries. e.g. https://www.youtube.com/watch?v=RhfyP8pEEc4 |
@optiks Thanks! I understand the approach you've shown offers much cleaner isolation between the boundaries. It's a bit of a tradeoff because:
I agree with you we need to be careful and make an informed decision! Thanks for your input it will be useful to discuss this with my team :-) |
@dazinator No worries at all. Just a couple more thoughts:
Good luck! |
@optiks An approach we considered that was closer to your #2 suggestion above, was having that second entity mapped to a SQL View instead, where the VIEW does the join to pull the additional data, and obviously doesn't allow inserts / updates or deletes. I think this is slightly safer, and less work at the EF level. However with this approach you lose compile time errors if changes are made to the user table / user entity, the T-SQL veiw can become broken, and your data model with the view entity compiles fine - oblivious to the error until runtime! Just mentioning it as this might work for some. |
@optiks Actually I think this might work:
In this scenario:-
I think this might be a good fit for us. Database objects would look like:
|
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 theUser
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 theUser
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:
Foo
entity in DbContext B, and sets a navigation property on theFoo
entity, to theUser
entity thats already been added to DbContext A, and was not tracked previously by DbContext B.Foo
entity to theUser
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 theUser
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
The text was updated successfully, but these errors were encountered: