Retrieve Entity Framework DbContext from a proxy object

March 7, 2012, Software Development

There are some situations where you need to get the DbContext from a proxy object generated by the Entity Framework (current version: 4.5). Every generated proxy object holds a reference to the ObjectContext it belongs to. The problem is, that the ObjectContext does not have any information or reference to the corresponding DbContext. My solution is to maintain a static list with a ObjectContext-DbContext-Mapping:

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;

namespace Sample
{
    public class MyDbContext : DbContext
    {
        private static readonly Dictionary<ObjectContext, MyDbContext> contexts = 
            new Dictionary<ObjectContext, MyDbContext>();

        public static MyDbContext FromObjectContext(ObjectContext context)
        {
            lock (contexts)
            {
                if (contexts.ContainsKey(context))
                    return contexts[context];
                return null; // context has propably been disposed
            }
        }

        public static MyDbContext FromObject(object obj)
        {
            var field = obj.GetType().GetField("_entityWrapper");
            var wrapper = field.GetValue(obj);
            var property = wrapper.GetType().GetProperty("Context");
            var context = (ObjectContext)property.GetValue(wrapper, null);
            return FromObjectContext(context);
        }

        public MyDbContext()
        {
            lock (contexts)
                contexts[((IObjectContextAdapter)this).ObjectContext] = this; 
        }

        protected override void Dispose(bool disposing)
        {
            lock (contexts)
                contexts.Remove(((IObjectContextAdapter)this).ObjectContext);
            base.Dispose(disposing);
        }

        // TODO: ADD YOUR DbSets HERE
    }
}

With these static methods, it is easy to retrieve the DbContext from a proxy object:

var ctx = MyDataContext.FromObject(person);

If you have found a better solution, feel free to inform me.

Tweet about this on TwitterShare on FacebookEmail this to someoneShare on TumblrShare on LinkedIn
zv7qrnb

Tags: , ,

Leave a Reply