Attaching Entities when using ObjectContext having lifetime of Http Request
- 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 :will give error if 'Category' with CategoryId = CategoryIdSelected exists in ObjectContext.Category newCategory = new Category {CategoryId = CategoryIdSelected}; ctx.AttachTo("CategorySet", newCategory);
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
- 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? - 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); - i don't understand what your code is trying to acomplish.
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.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.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.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.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.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=507482To 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


