Data Access from Entity framework works during deb

2019-07-13 23:43发布

问题:

I got unique situation in my Entityframework web application, I'm trying to load the fields in page through list but its keep saying "The objectContext insteance has been disposed and can no longer be used for operations that require a connection." But when I set the debugging point and step into to see what is the error it works fine??

Here is my codes: This is Under my Page Load Event...

private void loadGPYouth()
{
  List<GPYouth> leader = GPYouthLoader.getGPYouth(ViewState["LeaderID"].ToString());
   foreach (var item in leader)
   {
   ddlConstituency.SelectedValue = item.Grampanchayat.ConstituencyID.ToString();
   ddlMandal.SelectedValue = item.Grampanchayat.MandalID.ToString();
   //filling remaing fields.....
   }
}

This is under GPYouthLoader class :

public static List<GPYouth> getGPYouth(string LeaderID)
{
  List<GPYouth> list = new List<GPYouth>();
  using (var db = new TDPMADANEntities())
  {
   int _id = Convert.ToInt32(LeaderID);
   var query = (from b in db.GPYouths where b.YouthID == _id select b).ToList();
   list = query.ToList();
  }
  return list;
}

And This is my GPYouth class :

public partial class GPYouth
{
    public long YouthID { get; set; }
    public Nullable<long> GPID { get; set; }
    //Remaining Fields....
    public virtual Grampanchayat Grampanchayat { get; set; }
}

回答1:

You're disposing your entity context (thanks to the using), so you can't lazy-load your Grampanchayat property after.

Remember lazy-loading requires to execute a new SQL request against the database, so if your connection to the DB is closed (which is, because you disposed the context) you can't lazy-load anything anymore.

It probably works in debug because the Visual Studio debugger itself tries to access to your Grampanchayat property before disposing the context (for example, to display it in the Watch window).

A proper correction to your issue would be to eager load (see this link for example ) navigation properties you're interested in, then dispose the context. All your GPYouth instances as well as all your Grampanchayat navigation properties will be fetched in one query from the DB. You won't need to execute SQL requests later using lazy-loading.

Don't let an entity context not disposed, try to shorten its lifetime as much as possible. Once you're done with it, dispose it. If anything goes wrong after, you'll know you've forgot to eager load a navigation property.

As a side note, I personally think using lazy-loading is a bad practice. Main points IMHO are: terrible performances if not used correctly (which is often the case), broken exception management (as you might fail to execute SQL on your DB anywhere is your code, not just in the DAL). I would disable it to avoid similar issues in the future.



回答2:

In my GPYouthLoader class I have taken out the using statement and it starts working fine.

public static List<GPYouth> getGPYouth(string LeaderID)
{
  List<GPYouth> list = new List<GPYouth>();
  int _id = Convert.ToInt32(LeaderID);
  var db = new TDPMADANEntities();
  var query = (from b in db.GPYouths where b.YouthID == _id select b).ToList();
  list = query.ToList();
  // You could directly set list = (from b....).ToList(); instead of list=query.ToList();
  return list;
}