List<Product> redProducts = null;
using (var ctx = new AdventureWorksContext())
{
redProducts = ctx.Products.Where(p => p.Color == "Red").ToList();
}
foreach (var p in redProducts)
{
Console.WriteLine("{0}: {1}", p.Name, p.ProductCategory.Name);
}
At run time, I get an exception:
Unhandled Exception: System.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.Notice that when iterating over the redProducts, I am accessing the ProductCategory navigation property. In Entity Framework 4.0, lazy loading is enabled by default. This means that when I access the ProductCategory property, the entity tries to retrieve the ProductCategory row from the database. However, I am outside of the using block, so the entity context has already been disposed.
One solution in this case is to simply eager load all the data I need before the entity context is disposed.
redProducts = ctx.Products.Include("ProductCategory").Where(p => p.Color == "Red").ToList();
Or, I could just pull down the two pieces of data that I need:
IList redProducts = null;
using (var ctx = new AdventureWorksContext())
{
redProducts = ctx.Products.Where(p => p.Color == "Red")
.Select(p => new { p.Name, Category = p.ProductCategory.Name })
.ToList();
}
foreach (dynamic p in redProducts)
{
Console.WriteLine("{0}: {1}", p.Name, p.Category);
}