众所周知,如果我们有一个EntityObject,则无法找到它所属的ObjectContext。这是公平的,我猜,但为什么我们可以延迟加载对象呢?当然,延迟加载的过程必须能够访问ObjectContext才能加载新对象吗?
答案 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
来进一步改进。也可以通过使用某种方法按名称获取属性值来简化它。