Chr*_*eis 11 .net lazy-loading objectdisposedexception objectcontext
我正在构建一个4层ASP.Net Web应用程序.这些图层是:
实体层具有我的数据模型类,并使用T4模板(POCO)从数据层中的实体数据模型(edmx文件)构建.实体层在所有其他层中引用.
我的数据层有一个名为SourceKeyRepository的类,它具有如下函数:
public IEnumerable<SourceKey> Get(SourceKey sk)
{
using (dmc = new DataModelContainer())
{
var query = from SourceKey in dmc.SourceKeys
select SourceKey;
if (sk.sourceKey1 != null)
{
query = from SourceKey in query
where SourceKey.sourceKey1 == sk.sourceKey1
select SourceKey;
}
return query;
}
}
Run Code Online (Sandbox Code Playgroud)
由于我不希望我的查询在此应用程序的其他层中运行,因此禁用了延迟加载.尝试访问UI层中的信息时,我收到以下错误:
ObjectContext实例已被释放,不能再用于需要连接的操作.
我确定这是因为我的DataModelContainer"dmc"被处理掉了.如何从我的数据层返回此IEnumerable对象,以便它不依赖于ObjectContext,而只依赖于DataModel?
有没有办法限制延迟加载只发生在数据层?
And*_*bel 18
query
是惰性求值,所以在枚举数据之前不会从数据库中检索数据.
如果你这样做:
return query.ToList();
Run Code Online (Sandbox Code Playgroud)
您将强制执行查询并避免此问题.
您收到错误消息,因为当调用者枚举集合时,ObjectContext(dmc
)已经处理了,这要归功于您的using
子句(这很好 - 早期配置数据库相关资源!)
在我使用的原始帖子AsEnumerable()
中我认为是正确的 - 直到我最近尝试在这种情况下自己使用它.AsEnumerable()
只进行编译时类型转换 - 它不枚举.要强制查询枚举,必须将其保存在一个List
或其他集合中.
例如,您可以在query
对象上调用某个方法
return query.AsEnumerable();
Run Code Online (Sandbox Code Playgroud)
这应该确保您执行查询,从而确保您以后不需要对象上下文.
不要用
return query.AsEnumerable();
Run Code Online (Sandbox Code Playgroud)
使用
return query.ToArray();
Run Code Online (Sandbox Code Playgroud)
在处理你的上下文之前.
返回AsEnumerable将不会执行foreach,直到引用该对象.将其转换为数组可确保在处理对象之前执行foreach.您可以将您的上下文放在一个使用块(您应该做的事情)中.