Reputation: 1277
I have a data layer that uses Entity Framework 5 to connects to Sql Server. I also have a LINQ query that gets some data. This query fails when used with Web API. I get the ObjectDisposedException. Here's the query:
using (MyContext container = new myContext())
{
return container.Sales
.Include("Products")
.Where(s => s.Id == id)
.FirstOrDefault();
}
The data layer is a dll, exposed by a business layer, also a dll, which is called by a web api controller. I had assumed that the JSON serializer was lazy loading the includes but none of my fixes have worked. Any ideas? I will update the question as need be if info is missing.
Here is the business layer call to the data layer:
public Sale GetSale(int id)
{
SaleRepository s = new SaleRepository();
return s.GetSale(id);
}
And finally the web api call to the business layer:
public Sale GetSale(int id)
{
SaleManager s = new SaleManager();
return s.GetSale(id);
}
Here is the exception:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Upvotes: 3
Views: 3050
Reputation: 6793
This is an issue with lazy loading. The more appropriate way to do this is to not dispose the DbContext
till the request is done processing. You can do it in a couple of ways,
1) dispose it in the controller. framework ties the controller's life time with the requests life time.
public class MyController : ApiController
{
private SaleManager _saleManager = new SaleManager();
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_saleManager.Dispose();
}
}
}
2) explicitly tie the resource with the request, (useful in cases where you are not inside a controller) using Request.RegisterForDispose()
SaleManager saleManager = new SaleManager();
Request.RegisterForDispose(saleManager);
Upvotes: 1
Reputation: 8907
This happens because lazy loading is being performed after your DbContext
has been disposed.
To resolve the issue you can disable lazy loading by doing this:
container.Configuration.LazyLoadingEnabled = false;
Upvotes: 2
Reputation: 14578
There must be an issue with lazy loading and the include not working as expected - try changing your code to select the actual object and the included entities.
using (MyContext container = new myContext())
{
var result = container
.Sales
.Include("Products")
.Where(s => s.Id == id)
.FirstOrDefault();
result.Products.ToList();
return result;
}
Upvotes: 1