ObjectContext实例已被处理,不能再用于需要连接的操作

本文关键字:用于 连接 操作 不能 实例 处理 ObjectContext | 更新日期: 2023-09-27 17:51:10

public List<User> Getdata()
{
     using (var context =new  huntableEntities())
     {             
         IQueryable<User> userrecords = (context.Users.Where(x => x.RecuiteReferalId == 24));
         userrecords.ToList().ForEach(u =>
                                         {
                                          u.CurrentCompany =
                                                 u.EmploymentHistories.Where(
                                                         e => e.IsCurrent && e.MasterCompany != null).Select(
                                                             e => e.MasterCompany.Description).FirstOrDefault();
                                                 u.CurrentPosition =
                                                     u.EmploymentHistories.Where(
                                                         e => e.IsCurrent && !string.IsNullOrEmpty(e.JobTitle)).
                                                         Select(e => e.JobTitle).FirstOrDefault();
                                         });
        return userrecords.AsEnumerable().ToList();
     }          
}

我在返回语句

处得到object context disposed

我尝试通过查询和方法IEnumerable,但结果是相同的。我还尝试通过设置延迟加载为false。

猜猜我哪里出错了?

ObjectContext实例已被处理,不能再用于需要连接的操作

在你调用ToList之后,你正在执行查询,因此从上下文断开实体-你需要在调用ForEach之前删除对ToList 的调用,即

userrecords.ForEach(u => ...);

同样,没有必要调用AsEnumerable,因为您的返回类型是List<User>,在返回查询之前只需调用ToList,即

return userrecords.ToList();

这不仅可以解决您的问题,而且更有效,因为您现在只需要访问数据库一次。

不使用扩展方法,而应该使用常规的Foreach循环来获得@James所说的好处。另外,您还可以清理您的LINQ查询:

foreach (var u in userrecords)
{
  u.CurrentCompany = u.EmploymentHistories
                      .FirstOrDefault(e => e.IsCurrent && e.MasterCompany != null)
                      .MasterCompany.Description;
  u.CurrentPosition = u.EmploymentHistories
                       .FirstOrDefault(e => e.IsCurrent && string.IsNullOrEmpty(e.JobTitle))
                       .JobTitle;
}

让它返回userrecords.ToList()

还有一件事要注意:如果在任何时候您尝试使用User记录上的导航属性,您也可能会得到相同的异常,因为连接已经关闭,并且它试图在没有连接的情况下延迟加载实体(因此失败)。在这种情况下,你可以关闭延迟加载,或者你可以,在这个方法中,实际调用该属性(不改变任何东西,只是读取它),让它在连接关闭之前加载。

不确定为什么在return列表时要处理上下文,但是代码中有一个狡猾的变化,无论如何都会产生意想不到的结果。您的ForEach声明不会改变任何东西!userrecords是一个IQueryable,你唯一要做的就是枚举它两次:在ForEach中,在return语句中的ToList()中。

你可以通过在开头创建一个列表来防止这种情况:

List<User> userrecords = context.Users
                        .Include("EmploymentHistories.MasterCompany")
                        .Where(x => x.RecuiteReferalId == 24)
                        .ToList();
userrecords.ForEach(u => ...

Include是为了防止n + 1查询。已处理的上下文现在应该不是问题了。