I have a DbSet which will have some of the entities loaded, not all. I want to retrieve the latest entity (including reloading it if required). However, I want to avoid hitting the database twice.
For a single entity - failed approach:
// Load entity
// If the entity is already in memory, this will not hit the database
// If the entity is not already loaded into memory, this will hit the database
var myCar = Context.Cars.FirstOrDefault(c => c.CarId == carId);
// Reload, in case the entity has changed in the database
// This will hit the database a second time, if the entity was NOT already loaded into memory
await Context.Entry(myCar).ReloadAsync().ConfigureAwait(false);
Convoluted approach:
// To retrieve from in-memory, use .Local:
var myCar = Context.Cars.Local.FirstOrDefault(c => c.CarId == carId);
if (myCar != null)
{
// Entity already loaded into memory
// It requires a reload
await Context.Entry(myCar).ReloadAsync().ConfigureAwait(false);
}
else
{
// Entity is not loaded into memory
// Load entity from database (don't use .Local)
myCar = Context.Cars.FirstOrDefault(c => c.CarId == carId);
}
This will only hit the db once, but is messy. I am looking for a single call that does this: "get the entity, ensuring it's the latest".
Edit for clarification:
The question is: How do I neatly and simply retrieve the contents of the database, in a clean and succinct manner, and ensure that the database is only hit once (ie: no redundant .Reload() to ensure I have the latest).
I know:
(a) If I have loaded the entity, there are definitely not any local changes. There may be changes from another user or process in the database. The question is "How do I hit the database once and only once" in order to get the changes from the other user. Calling FirstOrDefault is NOT loading the changes, hence I am calling Reload as well. (b) I may not have the entity in memory. I simply need to load the entity using FirstOrDefault. In which case, the Reload will hit the database again.
From the first answer:
The correct solution should be to ONLY call FirstOrDefault(), it should load the changes in the case of (a), or load the entity in case of (b).
My problem, however, now remains as follows:
I don't know why FirstOrDefault still isn't loading changes. Since I know that there are definitely no local changes (State == Unchanged), I would expect FirstOrDefault to load changes from the database, but it's not doing so. This is why I'm calling .Reload(), but instead I need to find out why FirstOrDefault is not loading the changes from the database, which will negate the need to call .Reload(). This will solve the issue.