为什么我们不能从EntityObject获取ObjectContext

时间:2011-07-29 06:56:18

标签: c# .net entity-framework

众所周知,如果我们有一个EntityObject,则无法找到它所属的ObjectContext。这是公平的,我猜,但为什么我们可以延迟加载对象呢?当然,延迟加载的过程必须能够访问ObjectContext才能加载新对象吗?

3 个答案:

答案 0 :(得分:4)

实际上你可以从ObjectContext获得EntityObject:它被描述为here ..

答案 1 :(得分:2)

你是对的,给定一个对象,我们不知道它属于哪个上下文,或者它附加到哪个会话。但是Lazy Loading就是这样的:

var firstPost = _Context.Posts.First()
var commentList = firstPost.Comments

当您说_Context.Posts.First()时,会加载一个帖子。 然后当你说firstPost.Comments加载评论列表的时候。

这是可能的,因为你的帖子中的评论字段的类型可能是IList或一些这样的通用界面:这是因为EF4可以放置代理列表而不是< em>实际评论列表。 代理列表了解_Context - 知道它附加到哪个会话或上下文。因此,它可以根据需要加载实际列表

答案 2 :(得分:2)

accepted answer的限制在于它只能在实体至少有一个关系时才能工作。

但是,这也可以通过反思来完成:

public ObjectContext Context(EntityObject entity) {
    var relationshipManager = ((IEntityWithRelationships)entity).RelationshipManager;
    var wrappedOwnerProperty = relationshipManager.GetType().GetProperty("WrappedOwner",BindingFlags.Instance | BindingFlags.NonPublic);
    var wrappedOwner = wrappedOwnerProperty.GetValue(relationshipManager);
    var contextProperty = wrappedOwner.GetType().GetProperty("Context");
    return (ObjectContext)contextProperty.GetValue(wrappedOwner);
}

在VB.NET中:

Function Context(entity As EntityObject) As ObjectContext
    Dim relationshipManager = DirectCast(entity, IEntityWithRelationships).RelationshipManager
    Dim wrappedOwnerProperty = relationshipManager.GetType.GetProperty("WrappedOwner", BindingFlags.Instance Or BindingFlags.NonPublic)
    Return wrappedOwnerProperty.GetValue(relationshipManager).Context
End Function

注意:这是在.NET Framework v.4.5.1下测试的。 YMMV,因为这取决于内部WrappedOwner属性和内部Context类的BaseEntityWrapper<TEntity>属性。然而,如果早期版本的.NET具有不同的内部属性/类,那么它应该足够简单,可以做类似的事情。

注意:这可以通过在EntityObject上使用扩展方法,并通过使用通用参数返回强类型ObjectContext来进一步改进。也可以通过使用某种方法按名称获取属性值来简化它。