C# 实体框架和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

我有一个数据层,它使用EntityFramework5连接到SQLServer。我还有一个获取一些数据的LINQ查询。与Web API一起使用时,此查询失败。我得到了ObjectDisposedException。问题是:

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;