I just found some really strange behaviour which turns out it is not so strange at all.
My select statement (query from database) worked only the first time. The second time, query from database was cached.
Inside Hub method I read something from database every 10 seconds and return result to all connected clients. But if some API change this data, Hub context does not read actual data.
In this thread I found this:
When you use EF it by default loads each entity only once per context. The first query creates entity instance and stores it internally. Any subsequent query which requires entity with the same key returns this stored instance. If values in the data store changed you still receive the entity with values from the initial query. This is called Identity map pattern. You can force the object context to reload the entity but it will reload a single shared instance.
So my question is how to properly use EFCore inside SignalR Core hub method?
I could use
AsNoTracking, but I would like to use some global setting. Developer can easily forget to add
AsNoTracking and this could mean serving outdated data to user.
I would like to write some code in my
BaseHub class which will tell context do not track data. If I change entity properties,
SaveChanges should update data. Can this be achieved? It is hard to think all the time to add
AsNoTracking when querying from hub method.
I would like to write some code in my BaseHub class which will tell context do not track data.
The default query tracking behavior is controlled by the ChangeTracker.QueryTrackingBehavior property with default value of
TrackAll (i.e. tracking).
You can change it to
NoTracking and then use
AsTracking() for queries that need tracking. It's a matter of which are more commonly needed.
If I change entity properties,
SaveChangesshould update data.
This is not possible if the entity is not tracked.
If you actually want tracking queries with "database wins" strategy, I'm afraid it's not possible currently in EF Core. I think EF6 object context services had an option for specifying the "client wins" vs "database wins" strategy, but EF Core currently does not provide such control and always implements "client wins" strategy.