views:

342

answers:

3

I am using the entity framework and I'm having a problem with "re-finding" objects I just created... basically it goes like this:

string theId = "someId";

private void Test()
{
  using(MyEntities entities = new MyEntities())
  {
    EntityObject o = new EntityObject();
    o.Id = theId;
    entities.AddToEntityObject(o);
    CallSomeOtherMethod(entities);
  }
}

void CallSomeOtherMethod(MyEntities ents)
{
  EntityObject search = ents.EntityObject.FirstOrDefault(o => o.Id == theId);
  if(search == null) 
  {
    Console.WriteLine("wha happened???");
  }
}

(no guarantee the code works btw - it's all from my head)

Why doesn't the query "find" the EntityObject that was just created?

If I call SaveChanges() after the AddToEntityObject it works (which doesn't surprise me) but why doesn't it pull from the cache properly?

I'm still green on this stuff so I'm hoping that there's some really easy thing that I'm just overlooking...

Thanks

+2  A: 

This happens because ents.EntityObject.WhatEver always queries the datasource. This is a design decision. They do it this way, because else they would have to execute the query against the datasource, against the local cache and then merge the results. As one of the developers pointed out in a blog (cannot remeber where exactly) they were unable to handle this consistently.

As you can imagine there are a lot of corner an edge cases you have to handle properly. You could just find a id you created localy, created by someone else in the database. This would force you to be prepeared to handle conflicts on (almost) every query. Maybe they could have made methods to querry the local cache and methods to query the datasource, but that is not to smart, too.

You may have a look at Transparent Lazy Loading for Entity Framework. This replaces the normal code generator and you get entites that populate their related entiy collections and entity references automaticaly on access. This avoids all the

if (!Entity.ReleatedEntities.IsLoaded)
{
   Entity.RelatedEntities.Load();
}

code fragments. And you can query the collections because they are always implicitly loaded. But this solution is not perfect, too. There are some issues. For example, if you create a new entity and access a collection of releated entities, you will get an exception because the code is unable to retrieve the releated entities from the database. There is also an issue concerning data binding and may be some more I am not aware of.

The good thing is that you get the source code and are able to fix the issues yourself and I am going to examin the first issue if I find some time. But I am quite sure that it will not be that easy to fix, because I exspect some case were just not hitting the database if the entity has just been created is not the exspected behavior.

Daniel Brückner
thanks for the tip/update ... i'm going to leave this question open for a while in hopes that someone can give me more info... but thanks
dovholuk
A: 

You have a number of options. You could extend the ObjectContext with another partial class to make your own mechanism for retrieving recently Added information.

Or you could just put an extension method on the ObjectContext that looks through the ObjectContext.ObjectStateManager looking for 'added' ObjectStateEntries, and then use LINQ to Objects to find what you are looking for.

Alex James
A: 

Check out this post

Abhijeet Patel