我收到此错误:
The ObjectContext instance has been disposed and can no
longer be used for operations that require a connection.
我理解为什么我收到错误。但是,我不明白为什么一种情况会导致错误而另一种情况不会导致错误。以下是两种情况。
案例一(导致错误):
List<SomeObject> someobjects;
using (var gm = new GenericRepository<SomeObject>())
{
someobjects = gm.Get().ToList();
}
vm.SomeObjectSelectList = slf.getSpecificList(someobjects);
这里发生的是List&lt;&gt;正在使用通用存储库从数据库填充。之后,该列表随后被发送到工厂(slf)以创建在视图模型(vm)中使用的选择列表。以这种方式使用时,会发生上述错误。原因是在工厂内部有这行代码:
w => w.Date + " " + w.Child.FirstName + " " + w.Child.LastName);
尽管someobjects的列表发送得很好,但它的嵌套对象却没有,并且当调用.Child时,会调用db context并导致错误。
案例二(没有错误):
List<SomeObject> someobjects;
using (var gm = new GenericRepository<SomeObject>())
{
someobjects = gm.Get().ToList();
vm.SomeObjectSelectList = slf.getSpecificList(someobjects);
}
在这种情况下,不会导致错误。但是,从第一种情况来看,很明显正在联系数据库上下文。
当上下文位于存储库内时,工厂如何访问上下文?
答案 0 :(得分:2)
工厂无权访问上下文 - someobjects
内部使用上下文在您第一次访问它们时检索属性值。由于您的上下文在使用块之后被释放,因此尝试访问属性将引发异常。
你可以想象,例如Child
属性实现是这样的:
private Person _child = null;
public Person Child
{
get
{
return _child ?? GetandSetChildFromContext();
}
}
仅在需要时才从上下文中懒惰地检索Child
的值 - 如果您想急切地包含相关属性,请使用Include()
查询 - 这是可取的,即如果您已经知道您将需要每次都有某些相关的属性。在EF上使用存储库层这一点有点困难 - 确保存储库支持包含查询。
答案 1 :(得分:1)
问题是using语句处理你的对象和你说的时间
someobjects = gm.Get().ToList()
;它不会复制它,但只是使用引用,如果你想让它工作,例如1工作,你将不得不将对象克隆到一个新的实例。
答案 2 :(得分:1)
实体通过延迟加载检索子数据。
答案 3 :(得分:1)
不是在一个限制范围的方法中创建存储库实例,而是可以将实例创建为控制器类的私有成员,并且可以将存储库配置在控制器的OnDispose方法中,以确保正确处理存储库。