2

I'm working on an application which will use EF5 as ORM.

Before start, I needed to create tests to confirm that everything in EF5 is working as it should. One of things I tested was support for UnitOfWork. I simulated multiple units of work by creating multiple instances of DbContext (like multiple requests when DbContext lifetime is set to PerWebRequest in IOC).

I encountered a suprise there, as EF5, as it seems uses something like SqlDependency, because I have situation as folows:

DbContext unit1 = new DbContext(), unit2 = new DbContext();
unit1.Items.Add(new Item() { Name = "Item1" });
Assert.AreEqual(0, unit1.Items.ToList().Count); // true as item is in unit1.Items.Local collection
Assert.AreEqual(0, unit2.Items.ToList().Count);

unit1.SaveChanges();

Assert.AreEqual(1, unit1.Items.ToList().Count); // true as unit1 is saved
Assert.AreEqual(1, unit2.Items.ToList().Count); // true as unit2 is somehow notified of changes

I am trying to find documentation but neither EF project pages and blogs nor google help me. This is not how old version of EF worked, where there was no out of the box feature to notify other contexts (i.e. see this question). It is nice if this is implemented but I need document which says it is, because I'm afraid that I cannot rely on this feature, and I cannot rely on knowing that data in my context won't change if other unit of work completes, as here obviously does.

Community
  • 1
  • 1
Goran Obradovic
  • 8,771
  • 8
  • 47
  • 77
  • 1
    Count goes to the database. If you save an Item in the database using one context and you try getting count using the other context it will return the current number of items in the database - it will be 1 since it will count the element that was saved in the database by the other context. I think it worked like this before as well. – Pawel Nov 18 '12 at 20:50
  • I have changed test to use Items.ToList().Count (updated in question also), and it produces same results, I remember about Count, I know that it had gone to DB every time you call it (without caching), but when you use ToList, it used to cache data. – Goran Obradovic Nov 18 '12 at 21:32
  • Well, ToList also goes into the database. – usr Nov 18 '12 at 21:45
  • @GoranObradovic ToList() enforces to evaluate the query and store results in the list. .Count on the list is using items in the List and not in the database to be counted. So if you do .ToList() and **then** add items to the database .Count on the list populated with .ToList() call will not change since you are counting the number of items cached in the list and you don't go to the database anymore. But as usr pointed out there is a trip to the database to get items to populate the list. – Pawel Nov 18 '12 at 21:57
  • Yes, there is trip to database to populate list, and first time, when there are 0 items, this trip is made and it should be cached in unit2, if I'm not mistaken? That is all clear, only last line is bothering me. – Goran Obradovic Nov 18 '12 at 23:22
  • .ToList() in the other config makes another trip to the database. Since data is in the database then it returns 1. There is no communication among contexts. Database is the common thing. If one context updates the database the other one will see the data when it goes to the database. – Pawel Nov 19 '12 at 22:06
  • Well, I could swear that in the previous versions of EF (3.x) this did not work this way, there was caching and only first time it had to go to DB, and later calls would not show new items, I remember that I needed to make explicit call to Reload method to show these. However, I would need to create project with old version to prove this. – Goran Obradovic Nov 19 '12 at 22:32

0 Answers0