Cannot access a disposed object. Object name: 'DataContext accessed after Dispose.'. This can happen if you send a Linq query result entity out of a procedure as shown below. The issues is that the inner procedure has not actually evaluated the query (i.e. results have not been retrieved from the SQL server, just the construct for the query exists). When you leave the inner procedure and attempt to access the data within the outer procedure the database context is gone (since it was wrapped in a using statement). Only at the point when you attempt to access the data members will the actual query results be requested from the SQL server and at that point there is no database context under which to execute the query. You may get the process to work by removing the using statement; however, that is not a correct practice. The better solution is to return an IEnumerable list using the .ToList() method on the result entity you are returning. This will force the query to execute and the full result set will be populated into the returned list.
Outer Procedure Code:
...
IEnumerable<BidMortgage.BMObject.LowestBid> bids = BidMortgage.BMObject.GetLowestBids();
/* Error here if not using .ToList<>() */
foreach (BidMortgage.BMObject.LowestBid bid in bids) {...}
...
Inner Procedure Code:
public class LowestBid
{
public LowestBid()
{
}
public int LoanTypeID { get; set; }
public string LoanTypeName { get; set; }
public decimal CalculatedAPR { get; set; }
public decimal InterestRate { get; set; }
}
public static IEnumerable<LowestBid> GetLowestBids()
{
DataTable tbl = new DataTable();
try
{
using (BidMortgage.BidMortgageDataContext db = new BidMortgageDataContext())
return (from row in db.LoanRequestBids
group row by row.tbl_LoanRequest.LoanTypeID
into g
select new LowestBid
{ LoanTypeID = g.Key
, LoanTypeName = (from itm in db.ListValues_MortgageTypes
where itm.TypeValue == g.Key
select itm.TypeName).SingleOrDefault()
, CalculatedAPR = g.Min(t => t.CalculatedAPR)
, InterestRate = (from itm in db.LoanRequestBids
where itm.CalculatedAPR == g.Min(t => t.CalculatedAPR)
&& itm.tbl_LoanRequest.LoanTypeID == g.Key
select itm.InterestRate).SingleOrDefault()
}).ToList<LowestBid>();
/*
If you don't use the .ToList<LowestBid>() and just return the select entity you will
receive this error when attempting to access the data outside of this using statement:
Cannot access a disposed object. Object name: 'DataContext accessed after Dispose.'.
*/
}
catch (Exception)
{
return null;
}
}