Reputation: 9075
I'm deep somewhere in the Business layer in a debugging session in Visual Studio trying to figure out why an Entity is behaving strangely when trying to persist the changes.
It would really be helpful to get a reference to the DbContext this Entity belongs to, at this point in the call stack.
I.e. to see what the state is of this Entity is (Unchanged, Modified, etc).
So I'm looking for a helper method like this:
var db_context = DbContextHelpers.GetDbContext(entity);
// after that I could do something like this
var state = db_context.Entry(entity);
I can use this stuff in the Immediate window during debugging.
Anyone any suggestions?
Extra notes
The Entity must be aware of the DbContext
somewhere, because it is using it for lazy loading navigation properties?
Upvotes: 35
Views: 42616
Reputation: 368
For EF6, I modified Dirk's answer slightly:
public static DbContext GetDbContextFromEntity(object entity)
{
var object_context = GetObjectContextFromEntity(entity);
if (object_context == null || object_context.TransactionHandler == null)
return null;
return object_context.TransactionHandler.DbContext;
}
private static ObjectContext GetObjectContextFromEntity(object entity)
{
var field = entity.GetType().GetField("_entityWrapper");
if (field == null)
return null;
var wrapper = field.GetValue(entity);
var property = wrapper.GetType().GetProperty("Context");
var context = (ObjectContext)property.GetValue(wrapper, null);
return context;
}
No new DbContext() and it's castable into your main Entities class.
Note: To the above question of null return value, this will happen if the entity has not been saved/committed. New entities that can only be found in .Local do not seem to have the "_entityWrapper" field.
Upvotes: 22
Reputation: 29444
I found another way to get ObjectContext. Don't know if it's any better though.
public static ObjectContext GetContext(this IEntityWithRelationships entity)
{
if (entity == null)
throw new ArgumentNullException("entity");
var relationshipManager = entity.RelationshipManager;
var relatedEnd = relationshipManager.GetAllRelatedEnds().FirstOrDefault();
if (relatedEnd == null)
throw new Exception("No relationships found");
var query = relatedEnd.CreateSourceQuery() as ObjectQuery;
if (query == null)
throw new Exception("The Entity is Detached");
return query.Context;
}
And you can use it like:
MyContext context = myEntity.GetContext() as MyContext;
Upvotes: 5
Reputation: 9075
public static DbContext GetDbContextFromEntity(object entity)
{
var object_context = GetObjectContextFromEntity( entity );
if ( object_context == null )
return null;
return new DbContext( object_context, dbContextOwnsObjectContext: false );
}
private static ObjectContext GetObjectContextFromEntity(object entity)
{
var field = entity.GetType().GetField("_entityWrapper");
if ( field == null )
return null;
var wrapper = field.GetValue(entity);
var property = wrapper.GetType().GetProperty("Context");
var context = (ObjectContext)property.GetValue(wrapper, null);
return context;
}
Upvotes: 28