It goes like this:
MyDbContext ctx = new MyDbContext();
IFooRepository repo = new FooRepository(ctx);
var items = repo.GetAvailableItem().ToList(); //this will query all item.sold = false.
// here it returns three rows
foreach(var item in items) {
item.sold = true;
}
repo.commit(); // this will call the SaveChanges() in DbContext
Thread.sleep(10000)
// Now I quickly execute a query in SQL Server Management Studio
// UPDATE Item SET Sold = 0;
var items02 = repo.GetAvailableItem().ToList(); // this will query all item.sold = false.
// here items02 also contains three rows
// HOWEVER, when I watch the value of item.sold in items02, it is all True
Is this the behavior by design?
Why? Is it because DbContext cache the entity and never refresh even if you run the same query again?
UPDATE
Here is the code in my repo:
public IQueryable<Item> GetAvailableItem()
{
var items = from x in DbContext.Item
where x.Sold == 0
select x;
return items;
}
public virtual int Commit()
{
return DbContext.SaveChanges();
}
OK. This is what happening:
GetAvailableItem()
If you want to your context know the changes outside itself, the easiest way is to create a new context and query again. Another way is to tell context explicity to re-load entities from db by yourContext.Entry<YourEntityType>(entityInstance).Reload();
.
My guess is that your DbContext
is not up to date with your changes that happened in the Database (you said that you are running an update during the Thread.sleep
). DbContext
won't pick up these updates (the data is cached).
That's why you want to have your lifescope of your context as short as possible to reduce concurrency. This is an expected behavior.
See this MSDN post
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.