none
Detach entity from DbContext in EF 4.1 code-first RRS feed

  • Question

  • I'm iterating through a very large collection, fetching an entity, retrieving an updated status from the web, and saving the changes to the database. A simplified version looks something like:

    private void UpdateFromWeb(HashSet<string> pksToUpdate)
    {
        using (var dbContext = new MyDbContext())
        {
            foreach (var pk in pksToUpdate)
            {
                var entity = dbContext.MyEntity1.Single(x=> x.ThePK == pk);
    //... //fetch updated status from web //... entity.Status = newValue; dbContext.SaveChanges(); } } }

    I'm experiencing heavy memory utilization which increments gradually as the loop progresses, peaking anywhere from 1-2 GB. Upon researching, I've concluded that I need to detach entities from the DbContext at the end of the iteration so that they are released (note that moving the call to SaveChanges() to outside of the loop doesn't affect the memory problem as the DbContext is still collecting all the entities being fetched and not releasing them after SaveChanges is called). This page suggests one should use:

    context.Entry(entity).State = EntityState.Detached;
    

    The problem with this is that VS prompts me to reference module System.Data.Entity 4.0.0.0. I was under the impression that one could not reference both EF 4.1 and 4.0 in the same code-first assembly.

    I would appreciate any guidance on this. Thanks in advance.

     

    PS: Someone suggested I use AsNoTracking(). But I do need to track changes to the entity (i.e. the updated status), so this doesn't work for me.





    • Edited by aardila Friday, November 11, 2011 6:24 PM
    Friday, November 11, 2011 4:11 PM

All replies

  •         foreach (var pk in pksToUpdate)
            {
                var entity = dbContext.MyEntity1.Single(x=> x.ThePK == pk);
    //... //fetch updated status from web //... entity.Status = newValue; dbCOntext.Entity(entity)=EntityState.Modified; }
    dbContext.SaveChanges();!!!!
            
    Friday, November 11, 2011 7:39 PM
  • myremember: Since you didn't say what this is supposed to improve or do differently, I can only assume you're referring to moving the SaveChanges() call to outside the loop.

    I mention in my original post that moving the call has no effect since the DbContext is still collecting all entities being retrieved at the top of the loop and not releasing them after SaveChanges() is called, thus utilizing an increasing amount of memory as it iterates. Calling SaveChanges() outside the loop would only make this more evident, as the DbContext would need to collect all entities in memory and track changes to the entities in memory before calling SaveChanges() once the loop completes.

    My question asks how to detach an entity, and why trying to assign an EntityState results in Visual Studio asking for a reference to EF 4.0. It is not clear how the code above does anything to address these points.

    Thanks.



    • Edited by aardila Monday, November 14, 2011 4:22 PM
    Monday, November 14, 2011 2:38 PM