In a previous post I blogged about Entity Framework (EF, v1.0 Beta 3) flaws, one of which was about the inconsistency between the entity context and the actual data in the database tables. Here I demonstrate it.
I have two tables: AddressField and Address with a many-to-many relationship as illustrated below.
In the database, the many-to-many relationship is representated as the address_addressfield table. EF correctly generated the entity model, which is shown below. In the entity model, Address has a collection of AddressField and vice versa. To avoid circular loops, lazy loading is used. So far, so good.
Suppose I have 3 addresses a1, a2 and a3, all of which are located in the same country, i.e. all 3 contain the same AddressField. Conversely, the AddressField representing the country should have 3 Addresses in its collection.
If I delete any Address, the corresponding database records in Address and Address_AddressField table should get removed. I would expect the same thing happens in the entity context - i.e. the deleted address should be removed from the AddressField's Address collection.
The following code snippet from my unit test illustrates this:
addressDao.Delete(a1); Assert.AreEqual(2, addressDao.GetAll().Length); addressDao.Delete(a2); addressDao.Delete(a3); Assert.IsNull(addressDao.GetAll()); Assert.AreEqual(0, afDao.CountAddressReferences(afCountry)); // test fails hereThe CountAddressReferences() method implementation is shown below:
public int CountAddressReferences(Address.Domain.AddressField af) { int id=(int) af.GetAddressFieldId(); AddressModel.AddressField entity = addressContext.AddressField .Where(t => t.addressFieldId == id).First(); entity.Address.Load(); return entity.Address.Count; }When I inspect the database tables, everything was OK - the Address table was empty and so was the Address_AddressField table. So the problem is in the entity context - it is not refreshed/updated following the association between Address and AddressField. To get around this problem, I had to detach and reattach the AddressField as shown below (lines 7 to 9):
public int CountAddressReferences(Address.Domain.AddressField af) { int id=(int) af.GetAddressFieldId(); AddressModel.AddressField entity = addressContext.AddressField .Where(t => t.addressFieldId == id).First(); entity.Address.Load(); Console.WriteLine("before count=" + entity.Address.Count); addressContext.Detach(entity); // extra line addressContext.Attach(entity); // extra line entity.Address.Load(); // extra line Console.WriteLine("after count=" + entity.Address.Count); return entity.Address.Count; }Inspecting the console output, it yielded:
before count=3 after count=0
No comments:
Post a Comment