I have a Blazor app that accesses data using EF Core. When a separate app edits state on the data, my Blazor app is not getting the data correctly when I reload it.
It fails to load when I try to get the whole set like this:
_context.Line.Where(i => i.id == id)
However what is even more confusing it does work if I were to do this:
_context.Line
.Where(i => i.id == id).Where(s => s.state != State.Recorded)
The second app changes some items that are of state “New” to state “Recorded”
If I only wanted to display the items that are not recorded, it works fine. Every time I reload the data from the context it knows to get the latest data. But if I try to get the whole set of items (which is what I need), it does not reload the data from DB it just shows the set as it was before, in other words with the sates as they were.
Is there any way i can force my context to get the data from the DB?
Also, why does it do it already when loading only partial data?
For more clarification, it does not work, if exclude items from the query that were not manipulated.
So for example if I were to say this:
_context.Line
.Where(i => i.id == id)
.Where(s => s.state != State.Flag)
it would be the same as if I tried getting the whole set.
2
This happens because Entity Framework uses tracking mechanism (doc and doc). If data was already fetched by the context and it is tracked then EF will only check if data was added/removed in the database but it will not remap the tracked data (i.e. if some columns were altered in the database)/
There are multiple options here (depending on the use case):
- Disable change tracking either globally or on per request basis with
AsNoTracking
. - Clear change tracker manually with
context.ChangeTracker.Clear();
call - Recreate the context (do not forget to dispose the old one) for example via DbContext factory
Also please see: How does caching work in Entity Framework?
3