一尘不染

解决“ ObjectContext实例已被处置,并且不能再用于需要连接的操作” InvalidOperationException

c#

我试图填充一个GridView使用Entity Frameworkm的方法,但是每次出现以下错误时:

“对象’COSIS_DAL.MemberLoan’上的属性访问器’LoanProduct’引发以下异常:ObjectContext实例已被处置,不能再用于需要连接的操作。”

我的代码是:

public List<MemberLoan> GetAllMembersForLoan(string keyword)
{
    using (CosisEntities db = new CosisEntities())
    {
        IQueryable<MemberLoan> query = db.MemberLoans.OrderByDescending(m => m.LoanDate);
        if (!string.IsNullOrEmpty(keyword))
        {
            keyword = keyword.ToLower();
            query = query.Where(m =>
                  m.LoanProviderCode.Contains(keyword)
                  || m.MemNo.Contains(keyword)
                  || (!string.IsNullOrEmpty(m.LoanProduct.LoanProductName) && m.LoanProduct.LoanProductName.ToLower().Contains(keyword))
                  || m.Membership.MemName.Contains(keyword)
                  || m.GeneralMasterInformation.Description.Contains(keyword)

                  );
        }
        return query.ToList();
    }
}


protected void btnSearch_Click(object sender, ImageClickEventArgs e)
{
    string keyword = txtKeyword.Text.ToLower();
    LoanController c = new LoanController();
    List<COSIS_DAL.MemberLoan> list = new List<COSIS_DAL.MemberLoan>();
    list = c.GetAllMembersForLoan(keyword);

    if (list.Count <= 0)
    {
        lblMsg.Text = "No Records Found";
        GridView1.DataSourceID = null;
        GridView1.DataSource = null;
        GridView1.DataBind();
    }
    else
    {
        lblMsg.Text = "";
        GridView1.DataSourceID = null;   
        GridView1.DataSource = list;
        GridView1.DataBind();
    }
}

错误是提到的LoanProductNameGridview。提及:我正在使用C#,ASP.net,SQL-Server 2008作为后端数据库。

我是实体框架的新手。我不明白为什么会收到此错误。谁能帮我吗?


阅读 773

收藏
2020-05-19

共1个答案

一尘不染

默认情况下,实体框架使用延迟加载来导航属性。这就是为什么应将这些属性标记为虚拟的原因-
EF为您的实体创建代理类,并覆盖导航属性以允许延迟加载。例如,如果您有此实体:

public class MemberLoan
{
   public string LoandProviderCode { get; set; }
   public virtual Membership Membership { get; set; }
}

实体框架将返回从该实体继承的代理,并向该代理提供DbContext实例,以允许稍后延迟加载成员资格:

public class MemberLoanProxy : MemberLoan
{
    private CosisEntities db;
    private int membershipId;
    private Membership membership;

    public override Membership Membership 
    { 
       get 
       {
          if (membership == null)
              membership = db.Memberships.Find(membershipId);
          return membership;
       }
       set { membership = value; }
    }
}

因此,实体具有用于加载实体的DbContext实例。那是你的问题。您对usingCosisEntities的用法有所了解。它在返回实体之前布置上下文。稍后某些代码尝试使用延迟加载的导航属性时,它会失败,因为此时已处理上下文。

要解决此问题,您可以使用后面将急需的导航属性加载:

IQueryable<MemberLoan> query = db.MemberLoans.Include(m => m.Membership);

这将预加载所有成员身份,并且不会使用延迟加载。有关详细信息,请参阅MSDN上的“
加载相关实体 ”。

2020-05-19