2

I created few static list for the records which are being used as look up during application cycle.

However when inspected on the memory profiler and see the object context is being disposed however the GC cannot collect the memory because it keeps in references.

Following is the code snippet (I thought using AsNoTracking would break the relationship between context and entity and would allow context to die in piece.)

            private static List<State> _states;

            public static List<State> States
            {
                get
                {
                    if (_states == null)
                        LoadStates();

                    return _states;
                }
            }

            private static void LoadStates()
            {
                using (LeadContextUoW leadContext = new LeadContextUoW())
                {
                    _states = leadContext.States.AllWithNoTracking.ToList();
                }
            }

Please let me know what is the wrong with this code that is causing memory leak.

Paresh Varde
  • 1,084
  • 3
  • 16
  • 39
  • 1
    AllWithNoTracking is not a standard EF extension unlike the AsNoTracking extension on IQueryable. Do you have access to the source code for the custom extension to make sure it is implemented correctly? – Rob Epstein Aug 04 '14 at 12:47
  • It is correctly implemented. Following is the definition: public IQueryable AllWithNoTracking { get { return DbSet.AsNoTracking().AsQueryable(); } } – Paresh Varde Aug 07 '14 at 11:16

1 Answers1

0

You have to explicitly detach the entities. In previous versions of EF, you could call context.Detach - but I believe this is the standard method in EF 6.

private static void LoadStates()
        {
            using (LeadContextUoW leadContext = new LeadContextUoW())
            {
                _states = leadContext.States.AllWithNoTracking.ToList();
                foreach(var state in _states)
                    leadContext.Entry(state).State = System.Data.Entity.EntityState.Detached;
            }
        }
Mike
  • 643
  • 3
  • 10
  • 3
    This shouldn't be necessary since the AsNoTracking extension of IQueryable will keep the returned objects from being cached by the context. – Rob Epstein Aug 04 '14 at 12:56
  • I agree with Rob. If I need to detach entities for such instance what is the use of AsNoTrackign? – Paresh Varde Aug 04 '14 at 13:10
  • I believe AsNoTracking still attaches the entity for the purpose of lazy loading. Tracking isn't the only reason for entities being attached to a context. As mentioned here: http://stackoverflow.com/questions/5599147/how-do-i-detach-objects-in-entity-framework-code-first AsNoTracking does not completely detach entities. – Mike Aug 04 '14 at 13:21
  • Mike I think you are probably right. As a confirmation I did debug and when AsNoTracking is used the entity state I see it Unchanged instead of detached. I will write a generic solution to detach all entities from the context before it is disposed. I will keep you guys posted on the result. – Paresh Varde Aug 04 '14 at 14:42
  • Detaching entity is not quite useful to me since it loses all it's navigation properties even if they were loaded before the disposal of context and detaching entity from the context. – Paresh Varde Aug 06 '14 at 10:32