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.

Tags: , ,

Leave a Reply