none
An object with the same key already exists in the ObjectStateManager (Entity Framework v1)

    Question

  • Hello everybody,

    I`m having some problems with a scenario when using the ADO.NET Entity Framework. I'm talking about v1 release in .Net 3.5 SP1.

    It goes like this:

    I have a Project object and it has a list of users attached to it. I load the project object, keep it in view state (i`m talking about an ASP.Net web application) and modify the related users colelctions.

    Now when i want to save the changes back to db i get this: "An object with the same key already exists in the ObjectStateManager". The code that i use to persist the changes looks like this:

    Code Snippet
    public override bool Save(IList<Projects> itemsList)
    {
    using (PManagerEntities entities = new PManagerEntities())
    {
    foreach (Projects p in itemsList)
    {
    EntityKey pKey = p.EntityKey;

    if (pKey != null)
    {
    object pObject;
    if (entities.TryGetObjectByKey(pKey, out pObject))
    entities.ApplyPropertyChanges(pKey.EntitySetName, p);
    // This adds the whole graph to the object state manager and saves the changes made to the actual project - this works fine
    }
    else
    {
    pKey = entities.CreateEntityKey("Projects", p);

    ObjectStateEntry pEntry = null;
    if (!entities.ObjectStateManager.TryGetObjectStateEntry(pKey, out pEntry))
    entities.AddToProjects(p);
    // Or adds a new project
    }

    foreach (ProjectsUsers pu in p.ProjectsUsers)
    {
    EntityKey puKey = pu.EntityKey;

    if (puKey == null)
    puKey = entities.CreateEntityKey("ProjectsUsers", pu);

    object puObject = null;
    if (entities.TryGetObjectByKey(puKey, out puObject))
    entities.ApplyPropertyChanges(puKey.EntitySetName, pu);
    else
    {
    ObjectStateEntry puEntry = null;
    if (!entities.ObjectStateManager.TryGetObjectStateEntry(puKey, out puEntry))
    entities.AddToProjectsUsers(pu);
    // If i try this i get: The object cannot be added to the ObjectStateManager because it already has an EntityKey
    // I i use attach it says: An object with a null EntityKey value cannot be attached to an object context.

    // Also if i remove the CreateEntityKey and make a check on pu.EntityKey (if not null TryGetObjectByKey else Attach) i get this: An object with the same key already exists in the ObjectStateManager.
    //This is where it crashes and i don`t know what to do to make it work this way.
    }

    }
    }

    entities.SaveChanges();

    return true;

    }
    }

    Can somebody please tell me what should I do in a scenario like this? I`ve managed to make it work but only if i keep the new collection of users in a separate collection and then try to sync it with the existing one. Can't there be some other way? What if the project is related not only to users but also to tasks, documents etc. ? Do i need to keep all of these colelctions separately if i want to change them on a single web page?

    Thanks,
    Paduraru Ionut.
    Wednesday, September 17, 2008 2:05 AM

Answers

  • To recap your scenario, you are updating a list of Projects, each of which references a collection of ProjectUsers. A Project can either be new, designated by a null EntityKey, or existing, in which case it has an EntityKey and you want to apply the property changes. A ProjectUser can also either be new, designated by a null EntityKey, or existing, in which case it has an EntityKey and you want to apply the property changes. What isn't entirely clear is what should happen to your relationships...how are you distinguishing between when a "new" relationship shoulod exist and when the relationship should already exist. One assumption you can make is that the relationship is "new" when it has either a new Project or a new ProjectUser on one side of the relationship.

     

    The issue you are running into is that the object graphs you are using are already connected, and the Add/Attach/AttachTo methods all work on an entire object graph and not a single object. The Entity Framework has this requirement because partially attached graphs are not supported.

     

    For this scenario, I think it is possible to work around this, but it will, as you point out, require you to keep these collections seperate until you are in the save call. For example, you could add a new IList TempProjectUsers to each Project class. On your page, rather than adding the ProjectUsers to the ProjectUsers collection before the Save call, add them to TempProjectUsers. The Save call can move them. You would be able to update your code as:

     

    Code Snippet

    public override bool Save(IList<Projects> itemsList)
    {
      using (PManagerEntities entities = new PManagerEntities())
      {

        // Handle the Project
        foreach (Projects p in itemsList)
        {
          EntityKey pKey = p.EntityKey;

          if (pKey != null)
          {
            object pObject;
            if (entities.TryGetObjectByKey(pKey, out pObject))

            {
              entities.ApplyPropertyChanges(pKey.EntitySetName, p);

            }

          }
          else
          {
            pKey = entities.CreateEntityKey("Projects", p);
            ObjectStateEntry pEntry = null;
            if (!entities.ObjectStateManager.TryGetObjectStateEntry(pKey, out pEntry))

            {
              entities.AddToProjects(p);

            }
          }

     

          // Handle the TempProjectUsers (individual ProjectUsers)
          foreach (ProjectsUsers pu in p.TempProjectsUsers)
          {
            EntityKey puKey = pu.EntityKey;
            if (puKey == null)

            {
              puKey = entities.CreateEntityKey("ProjectsUsers", pu);

            }

            object puObject = null;
            if (entities.TryGetObjectByKey(puKey, out puObject))

            {
              entities.ApplyPropertyChanges(puKey.EntitySetName, pu);

            }
            else
            {
              ObjectStateEntry puEntry = null;
              if (!entities.ObjectStateManager.TryGetObjectStateEntry(puKey, out puEntry))

              {
                entities.AddToProjectsUsers(pu);

              }

            }

          }

         

          // Handle the Project to ProjectUser relationships

          foreach (ProjectUsers pu in p.TempProjectUsers)

          {

            // If either end is Added, add the relationship, otherwise the relationship

            // already existed

            // This may not always be the case, so you might need two collections, one for

            // "Added" relationships, and one for "Existing" relationships

            if(p.EntityState == EntityState.Added ||

               pu.EntityState == EntityState.Added)

            {

              p.ProjectUsers.Add(pu);

            }

            else

            {

              p.ProjectUsers.Attach(pu);

            }

          }

        }

        entities.SaveChanges();

        return true;
      }
    }

     

     

    Jeff

    Saturday, September 20, 2008 5:08 AM
    Moderator

All replies

  • To recap your scenario, you are updating a list of Projects, each of which references a collection of ProjectUsers. A Project can either be new, designated by a null EntityKey, or existing, in which case it has an EntityKey and you want to apply the property changes. A ProjectUser can also either be new, designated by a null EntityKey, or existing, in which case it has an EntityKey and you want to apply the property changes. What isn't entirely clear is what should happen to your relationships...how are you distinguishing between when a "new" relationship shoulod exist and when the relationship should already exist. One assumption you can make is that the relationship is "new" when it has either a new Project or a new ProjectUser on one side of the relationship.

     

    The issue you are running into is that the object graphs you are using are already connected, and the Add/Attach/AttachTo methods all work on an entire object graph and not a single object. The Entity Framework has this requirement because partially attached graphs are not supported.

     

    For this scenario, I think it is possible to work around this, but it will, as you point out, require you to keep these collections seperate until you are in the save call. For example, you could add a new IList TempProjectUsers to each Project class. On your page, rather than adding the ProjectUsers to the ProjectUsers collection before the Save call, add them to TempProjectUsers. The Save call can move them. You would be able to update your code as:

     

    Code Snippet

    public override bool Save(IList<Projects> itemsList)
    {
      using (PManagerEntities entities = new PManagerEntities())
      {

        // Handle the Project
        foreach (Projects p in itemsList)
        {
          EntityKey pKey = p.EntityKey;

          if (pKey != null)
          {
            object pObject;
            if (entities.TryGetObjectByKey(pKey, out pObject))

            {
              entities.ApplyPropertyChanges(pKey.EntitySetName, p);

            }

          }
          else
          {
            pKey = entities.CreateEntityKey("Projects", p);
            ObjectStateEntry pEntry = null;
            if (!entities.ObjectStateManager.TryGetObjectStateEntry(pKey, out pEntry))

            {
              entities.AddToProjects(p);

            }
          }

     

          // Handle the TempProjectUsers (individual ProjectUsers)
          foreach (ProjectsUsers pu in p.TempProjectsUsers)
          {
            EntityKey puKey = pu.EntityKey;
            if (puKey == null)

            {
              puKey = entities.CreateEntityKey("ProjectsUsers", pu);

            }

            object puObject = null;
            if (entities.TryGetObjectByKey(puKey, out puObject))

            {
              entities.ApplyPropertyChanges(puKey.EntitySetName, pu);

            }
            else
            {
              ObjectStateEntry puEntry = null;
              if (!entities.ObjectStateManager.TryGetObjectStateEntry(puKey, out puEntry))

              {
                entities.AddToProjectsUsers(pu);

              }

            }

          }

         

          // Handle the Project to ProjectUser relationships

          foreach (ProjectUsers pu in p.TempProjectUsers)

          {

            // If either end is Added, add the relationship, otherwise the relationship

            // already existed

            // This may not always be the case, so you might need two collections, one for

            // "Added" relationships, and one for "Existing" relationships

            if(p.EntityState == EntityState.Added ||

               pu.EntityState == EntityState.Added)

            {

              p.ProjectUsers.Add(pu);

            }

            else

            {

              p.ProjectUsers.Attach(pu);

            }

          }

        }

        entities.SaveChanges();

        return true;
      }
    }

     

     

    Jeff

    Saturday, September 20, 2008 5:08 AM
    Moderator
  •  

    Hi Padel and Jeff,

     

    [Sorry for my english, i'm french]

     

    I have the same issue in my Northwind database test (post here in french : here)

     

    I try your solution Jeff but it does the same Exception here  :

     

    Code Snippet

    ObjectStateEntry puEntry = null;

     

    if (!entities.ObjectStateManager.TryGetObjectStateEntry(puKey, out puEntry))

    {

    entities.AddToProjectsUsers(pu);

    }

     

     

    It seems that the 0 ID (for the new item) already exist in ObjectStateManager ?
     
    I try a lot of think but i'd never find how to insert a new item.
     

     
    Here a litle translate of my question in the french forum :
     
    I work with Northwind database (VS 2008 SP1 and .Net 3.5 SP1)
     
    I want to modify a Customer (update some of the fields) and Add a new empty Order (all the field of Orders are Nullable and the PK is autogenerated)
     
    - CustomerBusiness.cs
    Code Snippet
    public class CustomersBusiness

       {

           public Customers GetCustomerById(string customerId)

           {

               Customers customer;

               using (NORTHWINDEntities context = new NORTHWINDEntities())

               {

                   customer = context.Customers.Include("Orders").First(c => c.CustomerID == customerId);

               }

               return customer;

           }

           public void UpdateCustomer(Customers newCustomer, Customers oldCustomer)

           {

               using (NORTHWINDEntities context = new NORTHWINDEntities())

               {               

    context.AttachUpdated(newCustomer);

    context.SaveChanges();

           

     }

      }

       }

     

     

     

    - default.aspx

    Code Snippet

    public partial class _Default : System.Web.UI.Page

       {

           public Customers Customer

           {

               get { return ViewState["Customer"] as Customers; }

               set

               {

                   if (ViewState["Customer"] == null)

                   {

                       ViewState["Customer"] = value;

                   }

               }

           }

           public Customers CustomerOld

           {

               get { return ViewState["CustomerOld"] as Customers; }

               set

               {

                   if (ViewState["CustomerOld"] == null)

                   {

                       ViewState["CustomerOld"] = value;

                   }

               }

           }

           private Business.CustomersBusiness business = new Business.CustomersBusiness();

           protected void Page_Load(object sender, EventArgs e)

           {          

               this.CustomerOld = business.GetCustomerById("ALFKI");

               this.Customer = this.CustomerOld;

           }

           protected void Button1_Click(object sender, EventArgs e)

           {           

    this.Customer.CompanyName = "Test";

    Orders order = new Orders();

    Orders order2 = new Orders();

    this.Customer.Orders.Add(order);

    this.Customer.Orders.Add(order2);

    business.AddOrderToCustomer(this.Customer);

           }

       }

     

     

    ContextAttachUpdateExtension.cs

    Code Snippet

    public static class ContextAttachUpdateExtension

    {

    public static void AttachUpdated(this ObjectContext obj, EntityObject objectDetached)

    {

    if (objectDetached.EntityState == EntityState.Detached)

    {

    foreach (PropertyInfo property in objectDetached.GetType().GetProperties())

    {

    if (property.PropertyType.BaseType.Equals(typeof(RelatedEnd)))

    {

    IRelatedEnd relatedEnd = property.GetValue(objectDetached, null) as IRelatedEnd;

    foreach (object relatedItem in relatedEnd)

    {

    obj.AttachUpdated((EntityObject)relatedItem);

    }

    }

    object original = null;

     

    if (obj.TryGetObjectByKey(objectDetached.EntityKey, out original))

    {

    obj.ApplyPropertyChanges(objectDetached.EntityKey.EntitySetName, objectDetached);

    }

    else

    {

    throw new ObjectNotFoundException();

    }

    }

    }

    }

    }

     

     

     
    Sunday, September 21, 2008 9:47 AM
  •  

    I finaly found a way to do the job : (source here)

     

    It could be better but it's working

     

    Code Snippet

    public static class ContextAttachUpdateExtension

    {

    public static void AttachUpdated(this ObjectContext context, EntityObject objectDetached)

    {

    if (objectDetached.EntityState == EntityState.Detached)

    {

    int count = objectDetached.GetType().GetProperties().Length;

    for (int i = 0; i < count; i++)

    {

    PropertyInfo property = objectDetached.GetType().GetProperties()[i];

    if (property.PropertyType.BaseType.Equals(typeof(RelatedEnd)))

    {

    IRelatedEnd relatedEnd = property.GetValue(objectDetached, null) as IRelatedEnd;

    List<object> objs = new List<object>();

    foreach (var relatedItem in relatedEnd)

    {

    objs.Add(relatedItem);

    }

     

    foreach (object relatedItem in objs)

    {

    context.AttachUpdated((EntityObject)relatedItem, objectDetached);

    }

    }

    if (objectDetached.EntityKey != null)

    {

    object original = null;

    if (context.TryGetObjectByKey(objectDetached.EntityKey, out original))

    {

    context.ApplyPropertyChanges(objectDetached.EntityKey.EntitySetName, objectDetached);

    }

    else

    {

    throw new ObjectNotFoundException();

    }

    }

    }

    }

    }

     

    public static void AttachUpdated(this ObjectContext context, EntityObject objectDetached, EntityObject attachedRelation)

    {

    if (objectDetached.EntityKey != null)

    {

    context.AttachUpdated(objectDetached);

    }

    else

    {

    if (objectDetached.EntityState == EntityState.Detached)

    {

    int count = objectDetached.GetType().GetProperties().Length;

    for (int i = 0; i < count; i++)

    {

    PropertyInfo property = objectDetached.GetType().GetProperties()[i];

    if (property.PropertyType.BaseType.Equals(typeof(RelatedEnd)))

    {

    IRelatedEnd relatedEnd = property.GetValue(objectDetached, null) as IRelatedEnd;

    foreach (object relatedItem in relatedEnd)

    {

    context.AttachUpdated((EntityObject)relatedItem, objectDetached);

    }

    }

    else

    {

    if (property.PropertyType.Equals(attachedRelation.GetType()))

    {

    object o;

    if (context.TryGetObjectByKey(attachedRelation.EntityKey, out o))

    {

    property.SetValue(objectDetached, o, null);

    }

    }

    }

    }

    }

    }

    }

    }

     

     

     

     

    let me know if you find bugs or if you could writte better code,especially this part :

     

    Code Snippet

    IRelatedEnd relatedEnd = property.GetValue(objectDetached, null) as IRelatedEnd;

    List<object> objs = new List<object>();

    foreach (var relatedItem in relatedEnd)

    {

    objs.Add(relatedItem);

    }

     

    foreach (object relatedItem in objs)

    {

    context.AttachUpdated((EntityObject)relatedItem, objectDetached);

    }

     

     

     

     

    Now i try to found a way for deleted object.....

     

    Sunday, September 21, 2008 1:14 PM
  • First of all thanks to all...

    I haven`t tried the first piece of code as i mentioned i want to avoid using additional lists for related objects.

    Also, unfortunately the second piece of code doesn`t work also (i get "Exception has been thrown by the target of an invocation" with inner exception "The object cannot be added to the ObjectStateManager because it already has an EntityKey. Use ObjectContext.Attach to attach an object that has an existing key.").

    Maybe it`s because ef entities look loke this:



    ...and the problem is probably because the ProjectsUsers has a composed PK. I can`t add it because isn`t autogenerated and i can't attach it because it looks to be null (the EntityKey).

    Another issue is: if i use applypropertychanges and the whole graph is attached why can`t i see what exactly is attached? This is the process i don`t understand. If an object (and related objects in graph) are attached shouldn`t context.ObjectStateManager.TryGetObjectStateEntry(....) should return true for an object that belongs to the graph? Where are these objects added?

    Also if i try to attach one to the original object obtained by TryGetObjectByKey (let`s say originalObject) like this:
    (originalObject as Projects).ProjectsUsers.Attach(pu); // pu is a detached ProjectsUsers object - it will say that the originalObject is attached to another context... There can be more than one context?

    The whole scenario is like this:

    1. get from db a project object with include called on all relations..
    2. store it in the viewstate and change it`s properties (that`s why i need applypropertychanges) and also add a projectsuser object to the project object' ProjectsUsers property (this involves more than one postback/save in viewstate).
    3 finally persist the changes for the project users and the new added projectsusers object (has an entity key set to null and this should cause insert) the existing ones should have an entity key set and applypropertychanges is fine in this case.

    Basically: add a new user to the project....

    Playing with this things and trying to get a solutions by using only the ef api i got into more interesting things...

    If i dispose the context after calling only applypropertychanges and then use another one the TryGetObjectByKey will return true for the objects in relation (ProjectsUsers in relation with Project) even though they aren't saved in the db (the SaveChanges from the first context won`t persist these objects from relations). I guess some cache is involved?

    Anyway the idea is to use only the Api from EF...

    Regards...
    Monday, September 22, 2008 11:23 PM
  •  

    Sorry but i don't understand why you want to use EF API only (and how?)  [French inside Smile ]

     

    Do you try my Extension class? because i think it solve your problem (or near).

     

    To use it you just need to add it in the project where you have the Entity schema, change the namespace and that's all...

     

    After that you just have to call ".AttachUpdated ()"  instead of  ".Attach()".

     

     

    For your example :

     

    Code Snippet

    public override bool Save(IList<Projects> itemsList)
    {

    using (PManagerEntities entities = new PManagerEntities())
    {

    foreach (Projects p in itemsList)
    {

    p.AttachUpdated();

    }

    }

    }

     

     

    And that's it...

     

    The only issue for the moment is the deleted item but I'm on it.

     

     

    Edit:

     

    I'm not sure to understand this part : "1. get from db a project object with include called on all relations.."

     

    Do you want to have all your entities with lazy loading ?

    Tuesday, September 23, 2008 11:40 AM
  • Well i`ve tried your code and i still get an exception as i mentioned earlier:

    "Exception has been thrown by the target of an invocation" with inner exception "The object cannot be added to the ObjectStateManager because it already has an EntityKey. Use ObjectContext.Attach to attach an object that has an existing key."

    i used it like this context.AttachUpdated(p); You mentioned
    p.AttachUpdated(); but AttachUpdated as i see in your code is and extension method for ObjectContext and not for EntityObject.

    The line that throws the exception is:

    property.SetValue(objectDetached, o, null);

    One more thing about your code: is there a special reason for including in the
    for (int i = 0; i < count; i++)
    { ... }

    the context.ApplyPropertyChanges(objectDetached.EntityKey.EntitySetName, objectDetached); (first extension method) ?

    What i meant with
    "get from db a project object with include called on all relations.." -> the code will speak for itself

     public override Projects Fetch(long id)
            {
                using (PManagerEntities entities = new PManagerEntities())
                {
                    Projects project = (from p in entities.Projects.Include("ProjectsUsers").Include("ProjectsUsers.Users").Include("ProjectsUsers.Positions") where p.Id == id select p).ToList<Projects>().FirstOrDefault<Projects>();

                    return project;
                }
            }

    In the first place i would be happy if it will work without lazy loading (as far as i know EF doesn`t work with lazy loading by default, but you can check for IsLoaded and call Load to load entities) ... Just load all related entities with "Include" for now...

    By using only EF Api i wanted to say that it should be possible to use in this scenario only methods and classes from ObjectContext, ObjectStateManager etc. classes from EF, and not try to struggle using reflection and workarounds (additional collections for added, deleted etc).

    I'm really interested in EF but if i can`t get things going without complicating them then what`s the point? Where is the "abstraction"? In helper methods?


    Tuesday, September 23, 2008 12:58 PM
  •  

    "i used it like this context.AttachUpdated(p); You mentioned p.AttachUpdated(); but AttachUpdated as i see in your code is and extension method for ObjectContext and not for EntityObject."

    Mistake and you correction is right.

     

     

    "By using only EF Api i wanted to say that it should be possible to use in this scenario only methods and classes from ObjectContext, ObjectStateManager etc. classes from EF, and not try to struggle using reflection and workarounds (additional collections for added, deleted etc)."

     

    Then we are two

     

     

    I try for about 3 week to find a way to not use helpers methods but i didn't find anything else...

     

    I think EF v1 is just a "testing community reaction"  to know what modify in v2 (i hope).

     

    I read that EF v2 should probably have lazy loading and could be really attached to a context when detach and attach automatically the graph...

     

    For the moment, i use this code with reflexion and it work (for me) without problems.

     

     

    for the :

    for (int i = 0; i < count; i++)
    { ... }

     

    i use this because when you attach part of graph it modify the collection then you can't use foreach nor .Next()...

    but sure it's not a great code i'm not a professionnal

    Wednesday, September 24, 2008 4:50 PM
  • I finally figured it out so here`s the working code... It can be further optimized/changed to suite different needs but this i`ll do later.

    public override bool Save(IList<Projects> itemsList)
    {
        using (PManagerEntities entities = new PManagerEntities())
        {
            foreach (Projects p in itemsList)
            {
                List<ProjectUsers> newProjectUsers = p.ProjectUsers.Where(pu => pu.EntityKey == null).ToList<ProjectUsers>();

                newProjectUsers.ForEach(pu => p.ProjectUsers.Remove(pu));

                EntityKey pKey = p.EntityKey;

                if (pKey != null)
                {
                    object pObject;
                    if (entities.TryGetObjectByKey(pKey, out pObject))
                    {
                        entities.ApplyPropertyChanges(pKey.EntitySetName, p);

                        (pObject as Projects).ProjectUsers.Load();

                        List<ProjectUsers> deletedProjectUsers = (pObject as Projects).ProjectUsers.Where(dPu => !p.ProjectUsers.Any(ePU => ePU.EntityKey == dPu.EntityKey)).ToList<ProjectUsers>();

                        foreach (ProjectUsers newPu in newProjectUsers)
                        {
                            Users user = newPu.Users;
                            Positions position = newPu.Positions;

    // If these are set an entity key will be generated instead (only attach will work and i don`t want to have the object beeing attached with unchanged entity state) and i can`t use addobject
                            newPu.Projects = null;
                            newPu.Positions = null;
                            newPu.Users = null;

                            entities.AddObject("ProjectUsers", newPu);

                            newPu.ProjectsReference.EntityKey = (pObject as Projects).EntityKey;
                            newPu.UsersReference.EntityKey = user.EntityKey;
                            newPu.PositionsReference.EntityKey = position.EntityKey;
                        }

                        foreach (ProjectUsers dPu in deletedProjectUsers)
                        {
                            entities.Attach(dPu);
                            entities.DeleteObject(dPu);
                        }


                    }
                }
                else
                {
    // This just adds the project... It doesn`t update referenced entities in relations.
                    pKey = entities.CreateEntityKey("Projects", p);

                    ObjectStateEntry pEntry = null;
                    if (!entities.ObjectStateManager.TryGetObjectStateEntry(pKey, out pEntry))
                        entities.AddToProjects(p);
                }
            }
            int affected = entities.SaveChanges();


            entities.Dispose();

            return affected != 0;
        }
    }

    After looking in System.Data.Entity.dll I think i figured it out how things work... If you have any question i`ll try to answer... And yes it can be done without reflection reflection but not without small tricks to make it work...

    A nice day to everyone...

    Thursday, September 25, 2008 9:51 PM
  • I'll try it later and tell you if it do the job for me

     

    Friday, September 26, 2008 3:48 PM
  •  Jeff Derstadt - MSFT wrote:

     

    The issue you are running into is that the object graphs you are using are already connected, and the Add/Attach/AttachTo methods all work on an entire object graph and not a single object. The Entity Framework has this requirement because partially attached graphs are not supported.

     




    Hi Jeff,


    Has anything changed compared to a previous release?
    Because this seems in contradiction to the documentation for attach on msdn (http://msdn.microsoft.com/en-us/library/bb896271.aspx):



    -----

    Call Attach on ObjectContext to attach the object to the object context. Do this when the object already exists in the data source but is currently not attached to the context. For more information, see How to: Attach Related Objects (Entity Framework)


    If the object being attached is related to other objects, you must explicitly define the relationships in one of the following ways:

    • Attach both objects to the object context, and then call Attach on EntityCollection or EntityReference to define the relationship.

    • If neither object is attached, call Add on EntityCollection and specify the related object or set the Value property of EntityReference to the related object. Next, attach the root of the object graph to the object context. You can use this method to construct an object graph from detached objects and then attach the graph to the object context.

    These methods are used when attaching related objects that were serialized by using XML serialization.


    -----
    Wednesday, November 12, 2008 11:30 AM