3

i need to update 100 records on a single button click using entity framework 4.1 (POCO). I need to save the modified records in the database without doing database roundtrip (to avoid performance issue).

I have seen some solution with detach and attach.

getting error on attach An entity object cannot be referenced by multiple instances of IEntityChangeTracker

so tried detach first, get the new error The object cannot be detached because it is not attached to the ObjectStateManager

i am using repository pattern to get list of entities and passing to UI layer for binding in the grid.

in the button click, I am passing these entities back DB layer to update.

it works fine, with select the entity and do the context.applychanges. I need to avoid this round trip, for performance issue.

    public void Update(OPRPortCall portCall)
    {
        using (VMEntities context = new VMEntities())
        {
            context.Detach(portCall); //The object cannot be detached because it is not attached to the ObjectStateManager.
            context.AttachTo("OPRPortCalls", portCall); //An entity object cannot be referenced by multiple instances of IEntityChangeTracker
            context.ObjectStateManager.ChangeObjectState(portCall, EntityState.Modified);

            context.SaveChanges();
        }
    }

advise me any solution for this.

christopher

ChristopherJ
  • 51
  • 1
  • 5
  • Can you post the update code? Specifically, when you open and close the dbcontext. – Davin Tryon Feb 21 '13 at 11:07
  • "so tried detach first, get the new error" -- You need to detach it from the context it is attached to. It isn't attached to your new context, so detaching it from your new context does not and cannot work. But if you still have the old context around (and you do, otherwise the entity couldn't be attached to it), why not just call `SaveChanges()` on that old context? –  Feb 21 '13 at 11:22
  • dtryon updated the code. please check. – ChristopherJ Feb 21 '13 at 11:22
  • hvd. you may be right. but I cant maintain the old context for update operation due to layered structure. we are creating new context for update method. – ChristopherJ Feb 21 '13 at 11:30
  • @ChristopherJ Then perhaps you could detach the objects from your old context earlier, or not attach them to your old context in the first place (`.AsNoTracking()`)? –  Feb 21 '13 at 11:31
  • @hvd Used NoTracking and it works fine. `ObjectSet data = CreateObjectSet("OPRPortCalls"); data.MergeOption = MergeOption.NoTracking;` – ChristopherJ Feb 21 '13 at 12:41
  • related: http://stackoverflow.com/questions/15336248/entity-framework-5-updating-a-record?rq=1 – unairoldan Jul 14 '15 at 20:07

2 Answers2

1

Technically you can solve this by first testing whether the object is already attached or not:

public void Update(OPRPortCall portCall)
{
    using (VMEntities context = new VMEntities())
    {
        ObjectStateEntry ose;
        this.ObjectStateManager.TryGetObjectStateEntry(portCall, out ose);
        if (ose == null)
        {
            context.OPRPortCalls.Attach(portCall);
        }
        context.ObjectStateManager.ChangeObjectState(portCall, EntityState.Modified);

        context.SaveChanges();
    }
}
Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
0

You can Detach only entities retrieved from context, in your example you create the context (and in this moment there are no entities on it) after, you try a detach.

For the second problem I think you have another context where the entity has been attached, and for this reason you cannot attach the entity to the second context.

For this problems (attach/detach), avoid to create multiple contexts and use ONLY ONE context (maybe you can pass it as parameter on function or setup it as private class variable).

For the specific problem to update 100 entities you can: 1. Create a stored procedure if you can update same column for all entities (pass to it a value and execute UPDATE Statement) 2. Update all entities and after all call SubmitChages() with this command EF execute UPDATE TABLE 100 times 3. Execute a custom query command against database such as "UPDATE TABLE SET ..."

I hope this help.

Max
  • 6,821
  • 3
  • 43
  • 59