locked
Attach existing Object Graph with new subobjects problem... RRS feed

  • Question

  • Hi everyone,

    I am using Entity Framework 4 in my C# Windows application. I have two classes Project and Product. Project has a collection of Product's as property. This is a 1-To-Many relationship in my database. My application is N-Tiered, so after objects from database are load, they got detached from context. So if I want to save them again, I have to reattach the objects to the context.

    If I have a new Project, its easy to add it to the context using the AddObject Method. If Project were already existing, then I attach it to the context using the Attach method. I noticed, that all subobjects (in my case the collection of Products in Project) are also attached to context, if the parent object is attached.

    My problem begins if I want to attach an existing Project with two ore more NEW Products. Because Project is existing in db, I use the attach method (instead of AddObject), But then Entity Framework tries to also attach the two Products (as if they were also existing) and this throws an exception saying, there are existing two objects with the same ID.

    How can I say EF, attach the parent object, but ADD the two subobjects?

    Hope someone can help,
    regards...
    F/\nt/\sy PRODUCTIONS
    Thursday, February 11, 2010 7:35 AM

All replies

  • Hi there,

    so still no answer... Can anyone tell me, if I am the only one experiencing this problem, or is this a common issue?
    F/\nt/\sy PRODUCTIONS
    Tuesday, February 16, 2010 6:32 AM
  • I feel your pain, and there's not really much documentation on the subject on the NET yet... the reattach of nested objects seems to be a missing feature (i.e. only iterating for update non-collection based attributes)... if I detach my parent object, make mod's to a nested collection on the parent, reattach the parent (i reattach without error, however I haven't tried to do it with two new items as you have)...regardless, savechanges() doesn't reflect the modifications performed to the collection (i.e. try removing a few items, try updating a couple, and try adding a couple)... save changes + the state modify trick == i need to write some kind of object spinner for each of my pre-detach Include()'s...  

    :(

    Wednesday, January 12, 2011 7:12 PM
  • Hi,

    When re-attaching a graph that has added and existing objects it is better to start with an AddObject and then mark existing objects using ChangeObjectState, something like:

    // Marks project and all products as added
    context.Projects.AddObject(myProject);

    // Moves project to unchanged state
    context.ObjectStateManager.ChangeObjectState(myProject, EntityState.Unchanged);

    You might also find this post useful; http://romiller.com/2009/06/26/ntier-with-ef4-beta-1/

    ~Rowan

    Wednesday, January 12, 2011 8:17 PM
    Moderator
  • Where is AddObject on CTP5?  Am I missing something?  If I use ctx.Projects.Add(proj) + change state to Modified, i get my associations Doubled + the new ones == not what i was after... also, how to handle detecting deletes (removals) on a detached nested collection after it's reattached?

    I've been trying to get updates to my POCO model to work via WCF with re-Attach() for awhile now with little to no success... 

    I tried setting up a Find() and joining the results using LINQ... then I ran into problems saving the results back to the database because when WCF returns my lists, it returns fixed length arrays which I have to convert back to lists, etc... it gets real messy...so i abandoned that effort in hopes that a future release of EF would make life simpler.... 

    The state change is not present on my freshly re-attached POCO's, and it doesn't know that items have been removed, modified, or deleted.... i can do join operations to find the adds, deletes, but

    A straightforward end-to-end example would go along way... I looked at your ntier-with-ef4-beta-1, and i think we're talking apples vs oranges...

     

    Wednesday, January 12, 2011 9:29 PM
  • Hi,

    DbSet.Add is the equivalent of ObjectSet.AddObject, we took the opportunity to align the names with other Sets in the framework.

    Can you start up a separate thread with the code that is causing doubled associations etc? The N-Tier post all still applies with DbContext but the API surface is different so you would use context.Entry(myobject).State in place of ChangeObjectState.

    Tracking changes over multiple tiers is a hard problem and you may want to look at WCF Data Services. This builds on top of EF and takes care of all the change tracking etc for you.

    ~Rowan

    Thursday, January 13, 2011 9:24 PM
    Moderator
  • Hi Rowan,

    How do u change relationship state which used to be ChangeRelationshipState in your example. for instance if i add an order but one of the line is just modified but since the entire graph got imported in Added state i need to change the relationship between order and line in unchanged state? how do i do that in DbContext?


    Zeeshan Hirani Entity Framework 4.0 Recipes by Apress
    http://weblogs.asp.net/zeeshanhirani
    Thursday, January 13, 2011 10:03 PM
  • Hi Zeeshan,

    ChangeRelationshipState is not exposed via DbContext. We are trying to push folks towards using FK associations, especially for NTier scenarios, since it removes a lot of complications.

    ~Rowan

    Thursday, January 13, 2011 10:14 PM
    Moderator
  • well not having something similar to changerelationshipstate makes working with many-to-many association difficult also because that currently is represented as independent association.

    for instance i have received user object along with its roles from a wcf service. and i want to mark one of the roles the user is associated with as UnChanged because it currently existly

    db.Users.Add(user);

    db.Entry(user).State = UnChanged;

    db.ChangeTracker.Entries<Role>().ToList().Foreach(entry => entry.State = UnChanged);

    foreach(role in user.Roles)

    {

      if(//role exist for the user change the relationship state to unchange)
    {
         db.ObjectStateManager.ChangeRelationshipState(user,role, u => u.Roles,EntityState.UnChanged);


    }

    }

    Any ideas how i can achieve the above scenario?


    Zeeshan Hirani Entity Framework 4.0 Recipes by Apress
    http://weblogs.asp.net/zeeshanhirani
    Saturday, January 15, 2011 8:47 AM
  • Hi Zeeshan,

    Dropping down to the underlying ObjectContext is the correct thing to do in this case.

    ~Rowan

    Tuesday, January 18, 2011 12:45 AM
    Moderator
  • Hi,

    I have exactly the same problem: POCO, WCF. For scalar properties there is a solution. But for the associations?!

    I would really appreciate an example that shows how to deal with 1:M and M:M relationships.

    Thx

    Tuesday, March 29, 2011 5:40 AM