9

I'm trying to use Entity Framework to query database and I have following code that I'm using to get some data.

var students= MyEntities.Students.Where(s => s.Age > 20).ToList();

This code works fine and returns correct data. However, if I run this code, then go to database and update records to change the data this code should return, and then re-run this code without shutting down the app, I'm getting original data. I'm pretty sure it used to work fine, but now this doesn't refresh data.

James A Mohler
  • 10,562
  • 14
  • 41
  • 65
chiefanov
  • 1,004
  • 1
  • 10
  • 15

2 Answers2

16

No it never worked. This is essential behavior of entity framework (and many ORM tools) called identity map (explanation here).

If you run the query on the same context you will not get your entities updated. It will only append new entities created in the database between running those two queries. If you want to force EF to reload entities you must do something like this:

ObjectQuery query = MyEntities.Students;
query.MergeOption = MergeOption.OverwriteChanges;
var students = query.Where(s => s.Age > 20).ToList();
Community
  • 1
  • 1
Ladislav Mrnka
  • 349,807
  • 56
  • 643
  • 654
  • If you are just querying you should use `MergeOption.NoTracking` ? That would force the query to hit the db. – Nix May 25 '11 at 15:32
  • Query will hit DB anyway. I'm not sure what happens when you use `NoTracking` and you already have entities in the "cache" because when using lazy loading EF still keeps them. – Ladislav Mrnka May 25 '11 at 15:34
  • This seems to do what I want it to do. Using Refresh() method would work too, but I think using ObjectQuery is a cleaner solution. Marking this as the answer. However Nix brings a good point about best practices when using EF, which would be good to learn more about, so I'll need to look more into that. – chiefanov May 25 '11 at 16:38
6

You are running into issues because EF caches data, so if the data changes behind the scenes, and you dont dispose/reopen your context you are going to run into issues.

The general rule of thumb is to keep the lifetime of the context as short as possible, to circumvent issues like you just mentioned.

Please do not disregard what I said above, but if you would like to force a refresh from the DB you could use the Refresh() method.

Nix
  • 52,320
  • 25
  • 137
  • 193
  • Note that refresh is doing many queries for larger datasets, besides the actual query which may or may not get executed, while query.MergeOption is just forcing the query to be read from the database – yoel halb Dec 05 '13 at 00:05