Data Platform Developer Center > Data Platform Development Forums > ADO.NET Entity Framework and LINQ to Entities > Attaching Entities when using ObjectContext having lifetime of Http Request
Ask a questionAsk a question
 

QuestionAttaching Entities when using ObjectContext having lifetime of Http Request

  • Wednesday, November 04, 2009 6:30 AMASP.NET Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    I'm using .NET 3.5 SP1 in ASP.NET MVC application.
    While using ObjectContext with Http Request lifetime, and trying to attach an entity ALREADY present in context, we get error:
    "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key."
    For Example, the code :
    Category newCategory = new Category {CategoryId = CategoryIdSelected};
    ctx.AttachTo("CategorySet", newCategory);
    
    will give error if 'Category' with CategoryId = CategoryIdSelected exists in ObjectContext.

    Modified code to check for existing entity:
    Category newCategory = new Category {CategoryId = CategoryIdSelected};
    ObjectStateEntry stateEntry = null;
    
    if( csContext.ObjectStateManager.TryGetObjectStateEntry(newCategory, out stateEntry)){
       //EntityObject already attached in context, get it
        newCategory = (EntityObject)stateEntry.Entity;
    }else{
        ctx.AttachTo("CategorySet", newCategory);	
    }
    

    The modified code is still giving same error:
    "[System.InvalidOperationException] = {"An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key."

    Please advise ?

    Thank You

All Replies

  • Wednesday, November 04, 2009 11:03 AMhaberman michael Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    the ObjectStateManager allows that any EntityKey will be present only once.
    what your are trying to do iimpossible.

    can you explane what why you are trying to this?
  • Wednesday, November 04, 2009 1:00 PMASP.NET Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    What I'm trying to do is check for EntityObject  'Category' in ObjectContext via:
         if( csContext.ObjectStateManager.TryGetObjectStateEntry(newCategory, out stateEntry)){

    if not present then attach via:
         ctx.AttachTo("CategorySet", newCategory);
  • Wednesday, November 04, 2009 1:26 PMhaberman michael Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    i don't understand what your code is trying to acomplish.
  • Wednesday, November 04, 2009 3:02 PMJoao S Cardoso Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    The error is related to the fact that as soon as you havd an entity in the context with a key, you cant attach another entity with the same entity key to the same context.

    In order to do that need either to detach the entity from the model.

    I dont quite get your code but I assume that you want to create a new category? is that correct?

    If so the only thing you need to do is something like this (vb code :) :

    dim newCategory as new Category

    newCategory.CategoryId = CategoryIdSelected

    csContext.AddToCategory(newCategory)

    csContext.SaveChanges


    Please remember to mark the replies as answers if they help you.
  • Wednesday, November 04, 2009 5:47 PMNoam Ben-Ami - MSFTMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Try this:
    var key = csContext.CreateEntityKey("CategorySet", newCategory);
    if (csContext.ObjectStateManager.TryGetObjectStateEntry(key, out stateEntry)) {
    ...


    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Unmarked As Answer byASP.NET Tuesday, November 10, 2009 6:13 PM
    • Marked As Answer byASP.NET Thursday, November 05, 2009 3:01 PM
    •  
  • Thursday, November 05, 2009 3:05 PMASP.NET Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code

    Thanks Noam Ben-Ami. That is what I was looking for.

    Please note that, MSDN says for BOTH methods:

    ctx.ObjectStateManager.TryGetObjectStateEntry(Object, out stateEntry))

    and

    ctx.ObjectStateManager.TryGetObjectStateEntry(EntityKey, out stateEntry))

    will have: "A Boolean return value that is true if there is a corresponding ObjectStateEntry for the given EntityKey; otherwise, false."
    implying EntityKey is required for Entity STUB.

  • Tuesday, November 10, 2009 6:11 PMASP.NET Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Try this:
    var key = ctx.CreateEntityKey("CategorySet", newCategory);
    if (ctx.ObjectStateManager.TryGetObjectStateEntry(key, out stateEntry)) {
    ...


    This posting is provided "AS IS" with no warranties, and confers no rights.

    More problems attaching Entities when using ObjectContext having lifetime of Http Request.

    For Example, if we have 'AppUser','Category' and Department entities.

    public class AppUser : System.Data.Objects.DataClasses.EntityObject{  
     public int Uid {get; set;}  
     public string UserName {get; set;}  
     public string Password {get; set;}  
     public Department Dept {get; set;}  
     public Category catg {get; set;}
     ...........  
    }
    AppUser has relationship with Department and Category Entities.
    Now when trying to attach 'user':

    user = new AppUser{Uid=1,catg = new Category {categoryId=10}, Dept = new Department{departmentId=101}, ...}
    var key = ctx.CreateEntityKey("AppUserSet", user);
    if (ctx.ObjectStateManager.TryGetObjectStateEntry(key, out stateEntry)) {

    will work ONLY if, in context :
    - there is NO Category with categoryId=10, and
    - there is NO Department with departmentId=101

    One option, is to ensure context does not have attached entities by always retrieving using NOMERGE, which according to MSDN has overhead.


    Please advise.

    Thank You.

  • Tuesday, November 10, 2009 7:40 PMNoam Ben-Ami - MSFTMSFT, ModeratorUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    I don't know what MSDN says, but a non-tracking query should be the fastest way to query as fixup/key lookups are avoided. Can you point me at the MSDN article, please?

    Note that the EF enforces that all objects in a graph are attached or none are. This is probably why you are seeing the behavior you are seeing here.


    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Wednesday, November 11, 2009 7:29 PMASP.NET Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Thanks.
    I found following problems with MergeOption.NoTracking:
    - Second call would still result in db hit
    - You don't get EntityKeys on EntityRefs. So EntityKey of XXXReference is null,which means NO FK Stub. How to get EntityKey of Reference w/o loading both ends (both entities)?
    - Even though Entity are Detached, they have a reference to the DataContext (via entity._realtionships._context).
      https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=507482

    To keep things simple, is it just better to have method lifetime for context ?
     http://msdn.microsoft.com/en-us/library/cc853327.aspx: "you should create an ObjectContext instance within a using statement"
    Even here, entity graph needs to be explictly detached, else will have Unchaged state: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/5ee5db93-f8f3-44ef-8615-5002949bea71