Question

I am trying to add functionality in my ASP.NET MVC app to change some fields of my data structure. After clicking the submit button on the form, the following action is called:

    [HttpPost]
    public ActionResult Edit(Document doc)
    {
        // Attempt to save the project
        if (_documentService.SaveDocument(doc) == ServiceActionResult.Success)
            return RedirectToAction("List");
        else
            return View();
    }

The SaveDocument() method looks like this:

    public ServiceActionResult SaveDocument(Document doc)
    {
        if (doc == null)
            return ServiceActionResult.ActionFailure;

        // Check if this is a new Document (null ID)
        if (doc.Id == 0)
            _documentRepository.Add(doc);
        else
            _documentRepository.Attach(doc);

        _documentRepository.SaveChanges();

        return ServiceActionResult.Success;
    }

Since the document exists (and thus has an Id value), I call the Attach() method of my generic repository. The attach method just looks like:

    public void Attach(T entity)
    {
       _objectSet.Attach(entity);
    }

When the object set's Attach() method is called, the following exception occurs:

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

I don't understand why this is happening, since as you can see the whole lifecycle of the request only has one call to EF, and that's the final Attach(entity) call. Am I missing something?

As an FYI, this system used to work, but what seems to have broke it was my conversion from model first to code first with POCOs (latest CTP). All my other functionality works just as it did before, except for this scenario.

If it helps, my generic repository gets the ObjectSet from the DbContext via a function I wrote in my context class:

    public ObjectSet<T> CreateObjectSet<T>() where T : class
    {
        return ObjectContext.CreateObjectSet<T>();
    }


Edit: After looking around my code due to the comments I just remembered that I had implemented a singleton for context management. I did this due to the fact that it's possible a Controller may get entities from one service class, and use another service class to update it (I think that was the scenario I was trying to solve, I implemented it a while ago and I'd have to look closer when I get off of work).

I used a singleton for this because I had the impression that the singleton wouldn't go across multiple http requests, and I assume by the comments that that could be the issue. I'll look at this when I get home.

Was it helpful?

Solution

RE: as you can see the whole lifecycle of the request only has one call to EF

As far as we can see from the code shown, the ObjectContext lifetime could be the lifetime of the application. If it is, then that's probably the issue here.

Can you explain how you manage the ObjectContext lifetime .. is it per Http Request?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top