Ответ 1
Да, вы можете получить DbContext
от DbSet<TEntity>
, но это решение является тяжелым отражением. Я привел пример того, как это сделать ниже.
Я протестировал следующий код и смог успешно извлечь экземпляр DbContext
, из которого был создан DbSet
. Обратите внимание, что, хотя он отвечает на ваш вопрос, почти наверняка будет лучшим решением вашей проблемы.
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);
}
}
Пример использования:
using(var originalContextReference = new MyContext())
{
DbSet<MyObject> set = originalContextReference.Set<MyObject>();
DbContext retrievedContextReference = set.GetContext();
Debug.Assert(ReferenceEquals(retrievedContextReference,originalContextReference));
}
Объяснение:
Согласно Reflector, DbSet<TEntity>
имеет частное поле _internalSet
типа InternalSet<TEntity>
. Тип является внутренним для DLL EntityFramework. Он наследует от InternalQuery<TElement>
(где TEntity : TElement
). InternalQuery<TElement>
также является внутренним для dll EntityFramework. Он имеет частное поле _internalContext
типа InternalContext
. InternalContext
также является внутренним для EntityFramework. Однако InternalContext
предоставляет общедоступное свойство DbContext
, называемое Owner
. Итак, если у вас есть DbSet<TEntity>
, вы можете получить ссылку на владельца DbContext
, обратившись к каждому из этих свойств и передав окончательный результат в DbContext
.
Обновление @LoneyPixel
В EF7 есть частное поле _context непосредственно в классе, реализующее DbSet. Публиковать это поле публично не публично