Update relationships when saving changes of EF4 POCO objects?

"YOU AND THE ART OF ONLINE DATING" is the only product on the market that will take you step-by-step through the process of online dating, provide you with the resources to help ensure success. Get it now!

Let's try it this way: Attach BlogPost to context. After attaching object to context the state of the object, all related objects and all relations is set to Unchanged Use context. ObjectStateManager.

ChangeObjectState to set your BlogPost to Modified Iterate through Tag collection Use context. ObjectStateManager. ChangeRelationshipState to set state for relation between current Tag and BlogPost SaveChanges Edit: I guess one of my comments gave you false hope that EF will do the merge for you.

I played a lot with this problem and my conclusion says EF will not do this for you. I think you have also found my question on MSDN In reality there is plenty of such questions on the Internet. The problem is that it is not clearly stated how to deal with this scenario.So lets have a look on the problem: Problem background EF needs to track changes on entities so that persistance knows which records have to be updated, inserted or deleted.

The problem is that it is ObjectContext responsibility to track changes. ObjectContext is able to track changes only for attached entities. Entities which are created outside the ObjectContext are not tracked at all Problem description Based on above description we can clearly state that EF is more suitable for connected scenarios where entity is always attached to context - typical for WinForm application.

Web applications requires disconnected scenario where context is closed after request processing and entity content is passed as HTTP response to the client. Next HTTP request provides modified content of the entity which has to be recreated, attached to new context and persisted. Recreation usually happends outside of the context scope (layered architecture with persistance ignorace) Solution So how to deal with such disconnected scenario?

When using POCO classes we have 3 ways to deal with change tracking: Snapshot - requires same context = useless for disconnected scenario Dynamic tracking proxies - requires same context = useless for disconnected scenario Manual synchronization Manual synchronization on single entity is easy task. You just need to attach entity and call AddObject for inserting, DeleteObject for deleting or set state in ObjectStateManager to Modified for updating. The real pain comes when you have to deal with object graph instead of single entity.

This pain is even worse when you have to deal with independent associations (those that don't use Foreign Key property) and many to many relations. In that case you have to manually synchronize each entity in object graph but also each relation in object graph Manual synchronization is proposed as solution by MSDN documentation: Attaching and Detaching objects says: Objects are attached to the object context in an Unchanged state. If you need to change the state of an object or the relationship because you know that your object was modified in detached state, use one of the following methods Mentioned methods are ChangeObjectState and ChangeRelationshipState of ObjectStateManager = manual change tracking.

Similar proposal is in other MSDN documentation article: Defining and Managing Relationships says: If you are working with disconnected objects you must manually manage the synchronization Moreover there is blog post related to EF v1 which criticise exactly this behavior of EF Reason for solution EF has many "helpful" operations and settings like Refresh Load ApplyCurrentValues ApplyOriginalValues MergeOption etc. But by my investigation all these features work only for single entity and affects only scalar preperties (= not navigation properties and relations). I rather not test this methods with complex types nested in entity Other proposed solution Instead of real Merge functionality EF team provides something called Self Tracking Entities (STE) which don't solve the problem. First of all STE works only if same instance is used for whole processing.

In web application it is not the case unless you store instance in view state or session. Due to that I'm very unhappy from using EF and I'm going to check features of N First observation says that Nbernate perhaps has such functionality Conclusion I will end up this assumptions with single link to another related question on MSDN forum. Check Zeeshan He is author of Entity Framework 4.0 Recipes If he says that automatic merge of object graphs is not supported, I believe him But still there is possibility that I'm completely wrong and some automatic merge functionality exists in EF Edit 2.

Let's try it this way: Attach BlogPost to context. After attaching object to context the state of the object, all related objects and all relations is set to Unchanged. Use context.

ObjectStateManager. ChangeObjectState to set your BlogPost to Modified Iterate through Tag collection Use context. ObjectStateManager.

ChangeRelationshipState to set state for relation between current Tag and BlogPost. SaveChanges Edit: I guess one of my comments gave you false hope that EF will do the merge for you. I played a lot with this problem and my conclusion says EF will not do this for you.

I think you have also found my question on MSDN. In reality there is plenty of such questions on the Internet. The problem is that it is not clearly stated how to deal with this scenario.So lets have a look on the problem: Problem background EF needs to track changes on entities so that persistance knows which records have to be updated, inserted or deleted.

The problem is that it is ObjectContext responsibility to track changes. ObjectContext is able to track changes only for attached entities. Entities which are created outside the ObjectContext are not tracked at all.

Problem description Based on above description we can clearly state that EF is more suitable for connected scenarios where entity is always attached to context - typical for WinForm application. Web applications requires disconnected scenario where context is closed after request processing and entity content is passed as HTTP response to the client. Next HTTP request provides modified content of the entity which has to be recreated, attached to new context and persisted.

Recreation usually happends outside of the context scope (layered architecture with persistance ignorace). Solution So how to deal with such disconnected scenario? When using POCO classes we have 3 ways to deal with change tracking: Snapshot - requires same context = useless for disconnected scenario Dynamic tracking proxies - requires same context = useless for disconnected scenario Manual synchronization.

Manual synchronization on single entity is easy task. You just need to attach entity and call AddObject for inserting, DeleteObject for deleting or set state in ObjectStateManager to Modified for updating. The real pain comes when you have to deal with object graph instead of single entity.

This pain is even worse when you have to deal with independent associations (those that don't use Foreign Key property) and many to many relations. In that case you have to manually synchronize each entity in object graph but also each relation in object graph. Manual synchronization is proposed as solution by MSDN documentation: Attaching and Detaching objects says: Objects are attached to the object context in an Unchanged state.

If you need to change the state of an object or the relationship because you know that your object was modified in detached state, use one of the following methods. Mentioned methods are ChangeObjectState and ChangeRelationshipState of ObjectStateManager = manual change tracking. Similar proposal is in other MSDN documentation article: Defining and Managing Relationships says: If you are working with disconnected objects you must manually manage the synchronization.

Moreover there is blog post related to EF v1 which criticise exactly this behavior of EF. Reason for solution EF has many "helpful" operations and settings like Refresh, Load, ApplyCurrentValues, ApplyOriginalValues, MergeOption etc.But by my investigation all these features work only for single entity and affects only scalar preperties (= not navigation properties and relations). I rather not test this methods with complex types nested in entity.

Other proposed solution Instead of real Merge functionality EF team provides something called Self Tracking Entities (STE) which don't solve the problem. First of all STE works only if same instance is used for whole processing. In web application it is not the case unless you store instance in view state or session.

Due to that I'm very unhappy from using EF and I'm going to check features of NFirst observation says that Nbernate perhaps has such functionality. Conclusion I will end up this assumptions with single link to another related question on MSDN forum. Check Zeeshan He is author of Entity Framework 4.0 Recipes.

If he says that automatic merge of object graphs is not supported, I believe him. But still there is possibility that I'm completely wrong and some automatic merge functionality exists in EF. Edit 2: As you can see this was already added to MS Connect as suggestion in 2007.

MS has closed it as something to be done in next version but actually nothing had been done to improve this gap except STE.

This won't add the Tags, that's good. It adds the new relationships, that's also good. It doesn't remove the existing relationships.

That's bad :(. Using (var context = new Entities.Blog()) { context.BlogPosts. Attach(BlogPost); context.

ObjectStateManager. ChangeObjectState(BlogPost, System.Data.EntityState. Modified); foreach (Tag t in BlogPost.

Tags) { context. ObjectStateManager. ChangeRelationshipState(BlogPost, t, c => c.

Tags, System.Data.EntityState. Added); } context.DetectChanges(); context.SaveChanges(); } – foldip Sep 3 '10 at 13:12 It also fails when user edits the same BlogPost again and tried to save. It says: "An object with the same key already exists in the ObjectStateManager.

The ObjectStateManager cannot track multiple objects with the same key." On the line: context.BlogPosts. Attach(BlogPost); – foldip Sep 3 '10 at 13:14 But that are elementary principles when working with ORM.

You have to say context what was deleted.It didn't delete record which is not known. – Ladislav Mrnka Sep 3 '10 at 13:35 1 So after few month past, how about the Nbernate related to this issue compared to EF4? – CallMeLaNN 11/011 at 3:15 1 This is very well supported in Nbernate :-) no need to manually merge, in my example it's 3-level deep object graph, question has answers, each answer has comments, and question has comments too.

Nbernate can persist/merge your object graph, no matter how complex it is ienablemuch. Com/2011/01/nhibernate-saves-your-whole-object. Html Another satisfied Nbernate user: codinginstinct.Com/2009/11/… – Michael Buen 11/012 at 11:30.

I know it's late for the OP but since this is a very common issue I posted this in case it serves someone else. I've been toying around with this issue and I think I got a fairly simple solution, what I do is.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions