Yes, you can get the DbContext
from a DbSet<TEntity>
, but the solution is reflection heavy. I have provided an example of how to do this below.
I tested the following code and it was able to successfully retrieve the DbContext
instance from which the DbSet
was generated. Please note that, although it does answer your question, there is almost certainly a better solution to your problem.
public static class HackyDbSetGetContextTrick
{
public static DbContext GetContext<TEntity>(this DbSet<TEntity> dbSet)
where TEntity: class
{
object internalSet = dbSet
.GetType()
.GetField("_internalSet",BindingFlags.NonPublic|BindingFlags.Instance)
.GetValue(dbSet);
object internalContext = internalSet
.GetType()
.BaseType
.GetField("_internalContext",BindingFlags.NonPublic|BindingFlags.Instance)
.GetValue(internalSet);
return (DbContext)internalContext
.GetType()
.GetProperty("Owner",BindingFlags.Instance|BindingFlags.Public)
.GetValue(internalContext,null);
}
}
Example usage:
using(var originalContextReference = new MyContext())
{
DbSet<MyObject> set = originalContextReference.Set<MyObject>();
DbContext retrievedContextReference = set.GetContext();
Debug.Assert(ReferenceEquals(retrievedContextReference,originalContextReference));
}
Explanation:
According to Reflector, DbSet<TEntity>
has a private field _internalSet
of type InternalSet<TEntity>
. The type is internal to the EntityFramework dll. It inherits from InternalQuery<TElement>
(where TEntity : TElement
). InternalQuery<TElement>
is also internal to the EntityFramework dll. It has a private field _internalContext
of type InternalContext
. InternalContext
is also internal to EntityFramework. However, InternalContext
exposes a public DbContext
property called Owner
. So, if you have a DbSet<TEntity>
, you can get a reference to the DbContext
owner, by accessing each of those properties reflectively and casting the final result to DbContext
.
In EF7 there is a private field _context directly in the class the implements DbSet. It's not hard to expose this field publicly
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…