C# 实体框架和Web API ObjectDisposedException
我有一个数据层,它使用EntityFramework5连接到SQLServer。我还有一个获取一些数据的LINQ查询。与Web API一起使用时,此查询失败。我得到了ObjectDisposedException。问题是:C# 实体框架和Web API ObjectDisposedException,c#,entity-framework,serialization,asp.net-web-api,json.net,C#,Entity Framework,Serialization,Asp.net Web Api,Json.net,我有一个数据层,它使用EntityFramework5连接到SQLServer。我还有一个获取一些数据的LINQ查询。与Web API一起使用时,此查询失败。我得到了ObjectDisposedException。问题是: using (MyContext container = new myContext()) { return container.Sales .Include("Products") .W
using (MyContext container = new myContext())
{
return container.Sales
.Include("Products")
.Where(s => s.Id == id)
.FirstOrDefault();
}
数据层是由业务层公开的dll,也是由web api控制器调用的dll。我假设JSON序列化程序延迟加载includes,但我的任何修复都不起作用。有什么想法吗?如果信息丢失,我会根据需要更新问题
以下是对数据层的业务层调用:
public Sale GetSale(int id)
{
SaleRepository s = new SaleRepository();
return s.GetSale(id);
}
最后是对业务层的web api调用:
public Sale GetSale(int id)
{
SaleManager s = new SaleManager();
return s.GetSale(id);
}
例外情况如下:
ObjectContext实例已被释放,不能再用于需要连接的操作
延迟加载和include不能按预期工作一定存在问题-请尝试更改代码以选择实际对象和包含的实体
using (MyContext container = new myContext())
{
var result = container
.Sales
.Include("Products")
.Where(s => s.Id == id)
.FirstOrDefault();
result.Products.ToList();
return result;
}
这是延迟加载的一个问题。更合适的方法是在处理完请求之前不要处理
DbContext
。你可以用几种方法
1) 在控制器中进行处理。框架将控制器的生命周期与请求的生命周期联系起来
public class MyController : ApiController
{
private SaleManager _saleManager = new SaleManager();
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_saleManager.Dispose();
}
}
}
2) 使用
发生这种情况的原因是,在处置
DbContext
之后,正在执行延迟加载
要解决此问题,可以通过执行以下操作禁用延迟加载:
container.Configuration.LazyLoadingEnabled = false;
请显示您的异常以及代码在哪里?您是否尝试在DbContext实例上将
配置.LazyLoadingEnabled
设置为false以查看这是否解决了问题?看起来只有ObjectContext支持LazyLoadingEnabled。我正在使用DbContext。@CYAD DbContext也有。在您的情况下,您应该能够在查询之前调用container.Configuration.LazyLoadingEnabled=false
。@PeterHansen看起来这样做有效,谢谢!你能把它放在一个答案中,这样我就可以把它标记为已回答吗?问题是,这将数据层与服务层联系起来。我希望它们完全解耦。假设我们决定不喜欢实体框架?我们必须修改所有层以删除它。问题是,在释放DbContext之后,您正在使用从DbContext返回的实体。您的SaleManager和SaleRepository应该实现IDisposable,您可以在控制器中处置SaleManager。我正在更新我的答案,以便在控制器中使用SaleManager而不是DbContext。已尝试此操作。同样的结果。可能是我没有使用最佳实践。我看到的大多数示例都是从控制器查询数据。我想避免这种紧耦合。
container.Configuration.LazyLoadingEnabled = false;