What do you mean by "disaster"?
By default, EF will track references that it has already fetched. Do no confuse this with caching as being for a performance reason. Loading entire sets of entities as tracked references is not a good idea. Not because it still means extra round trips to the database despite that those instances are already tracked, but because the more instances that the EF DbContext
is tracking, the more memory is in use and the longer it can take to fetch additional data since those operations will automatically look to associate any already tracked instances for any relationships for the data being returned.
If you fetch a significant amount of data and don't need that data to be tracked by the DbContext (I.e. you don't intend to update it so you don't need change tracking ) then use AsNoTracking().
var users = App.Ctx.LoginUsers.AsNoTracking().ToList();
This will still fetch all users from the DB but the Context will not be tracking these instances.
If you know you have loaded the desired data already, or want to check and use any pre-loaded and tracked instances before going to the database, then use the Local
set from the DbSet to tell EF to just go to the tracking instances:
// Look for a tracked instance:
var user = App.Ctx.LoginUsers.Local.SingleOrDefault(x => x.UserId == userId);
if (user == null)
user = App.Ctx.LoginUsers.Single(x => x.UserId == userId);
This is a common strategy when you know some data might already be tracked and you are dealing with detached entities. (I.e. a user loaded with AsNoTracking
or deserialized) The Local
call checks the tracking store for that entity, so no round trip to the DB, then if we don't find it we can load and track it from the DB.
The other detail to be aware of is that while queries against the DbContext that would return an already tracked instance still trigger an SQL query, the tracked instance is not updated by the data returned by that query. For instance if you load your Users into the DbContext, then some other process not using that DbContext instance goes and modifies one or more of the users in the database, fetching those users from the DbContext will return the tracked data as it was when it was loaded. An SQL query will be run against the database, however any modified data state does not automatically update any of the already tracked entities.