views:

198

answers:

1

I am curious what the best practice is for this situation in Entity Framework 4.0. I have the following Entity Map:

Entity A -> Entity B -> Entity C

Where Entity A contains a list of Entity B's which each contains a list of Entity C's. I am using self tracking entities and when I load Entity A I am doing something similar to this:

EntityA entityA = ctx.EntityA.Include("EntityB").Where(x => x.Id == id).SingleOrDefault();

When I attempted to do this:

EntityA entityA = ctx.EntityA.Include("EntityB").Include("EntityC").Where(x => x.Id == id).SingleOrDefault();

It fails because it cannot find the navigation property 'Entity C'. Is there a way to load the navigation properties? I will also need to be able to Track Changes, Accept Changes, and MarkAsDeleted for my various CRUD operations.

As a side-question, is there a common Attribute used to identity a Navigation Property in Entity Framework? I was hoping to use reflection and recursion to identify all of my Navigation Properties.

+1  A: 

Try this out. It loads the navigation property from the current point in the object graph:

EntityA entityA = ctx.EntityA.Include("EntityB.EntityC").Where(x => x.Id == id).SingleOrDefault();

If you used the self tracking entities T4 template to generate your entities, then it should automatically track changes throughout your object graph.

After the self tracking T4 template is added to your project you can open it up and modify the file and add a custom attribute into the section that generates the navigation properties.

Wallace Breza
I did use a STE T4 template to generate my entities, however, I am still forced to do the following: foreach (EntityB entityB in entity.EntityB) entityB.AcceptChanges();
Brandon
Also, is there a way to automatically include navigation properties when loading an entity? Some sort of [Include] attribute?
Brandon
The `ObjectContext` has a property `ObjectContext.ContextOptions.LazyLoadingEnabled` but after trying this out myself I don't think it applies to the sef-tracking entities. Again, you're welcome to modify the T4 template to make it support lazy loading.
Wallace Breza
What happens if you just call `SaveChanges()` on your object context? All changes tracked on your entities should automatically be updated to the data store. How are you use these entities? Over WCF service, ASP.NET app, Rich client? Are they being detached from the context at some point and then you need to reattach and sync changes?
Wallace Breza
Correct, they are detached entities that I re-attach later on. If I do just a SaveChanges() and not an AcceptChanges() on each entity instance also, then the state of the entities does not get changed from Modified/Added to NotModified.
Brandon
There is also an overload on the `SaveChanges()` method so when you pass in `true`, `SaveChanges(true)`, it will automatically accept all changes on save. Also, I had problems in some cases that after I attached my entities back to the `ObjectContext`, they weren't being treated as modified. I was able to solve this by making a call to `ObjectStateManager.ChangeObjectState()` off the `ObjectContext` after attaching the entity.
Wallace Breza
@Brandon, @Wallace -- I have a similar question. Any chance you could have a look? http://stackoverflow.com/questions/3671193/entity-framework-how-to-force-all-navigation-property-items-to-load
Drew Noakes