“ ObjectContext实例已被处置,无法再用于需要连接的操作。”

时间:2018-11-23 09:08:47

标签: c# asp.net asp.net-web-api2 asp.net-identity

这个问题已经问了很多遍了。我想我解决了我的问题,但是由于我是初学者,并且仍然在学习,所以需要您的放心。

我为登录用户创建了扩展方法,但是当我在控制器中使用它时,会出现标题错误。

  

System.ObjectDisposedException:'ObjectContext实例已被处置,不能再用于需要连接的操作。'

因此,我进行了搜索和试验,并添加了以下代码行 在控制器中解决了我的问题。

db.Users.Attach(LoggedUser);

但是我不确定我的答案是否正确,因为有关此问题的很多答案都是禁用“延迟加载”,但最终并没有使用它。

这样的事情。

public class MyDbContext : DbContext
{
  public MyDbContext()
   {
    this.Configuration.LazyLoadingEnabled = false;
   }
}

这是我的扩展方法:

 public static ApplicationUser GetLoggedInUserInDB(this System.Security.Principal.IPrincipal _User)
    {
        using (var db = new ApplicationDbContext())
        {
            string userId = _User.Identity.GetUserId();
            var LoggedUser = db.Users.Find(userId);
            return LoggedUser;
        }
    }

我的控制器:

public class MainPageController : ApiController
{
    [Route("Personal_Project/Main_Page_Personal_Project/UserUnfo")]
    [ResponseType(typeof(string))]
    [Authorize]
    public IHttpActionResult GetUserInfo()
    {
        using (var db = new ApplicationDbContext())
        {
            var LoggedUser = User.GetLoggedInUserInDB();
            //db.Users.Attach(LoggedUser); // This is what I added to solve my problem.
            return Ok(new UserInfoModel
            {
                Name = LoggedUser.UserName,
                Reputation = LoggedUser.Reputation,
                UserLevel = LoggedUser.UserLevel
            });
        }
    }
}

那么“我的”解决方案很好吗?只需添加:

db.Users.Attach(LoggedUser);

这是合法的,还是这不是我们解决此问题的方式。任何建议将不胜感激

根据要求添加:

StackTrace:

  

ex.StackTrace“位于   System.Data.Entity.Core.Objects.ObjectContext.get_Connection()\ r \ n
  在System.Data.Entity.Core.Objects.ObjectQuery 1.GetResults(Nullable 1   forMergeOption)\ r \ n位于   System.Data.Entity.Core.Objects.ObjectQuery 1.Execute(MergeOption mergeOption)\r\n at System.Data.Entity.Core.Objects.DataClasses.EntityReference 1.Load(MergeOption   mergeOption)\ r \ n位于   System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.DeferredLoad()\ r \ n   在   System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.LoadProperty [TItem](TItem   propertyValue,字符串关系名称,字符串targetRoleName,布尔值   mustBeNull,对象wrapperObject)\ r \ n在   System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior。<> c__DisplayClass7`2.b__2(TProxy   代理,TItem项)\ r \ n位于   System.Data.Entity.DynamicProxies.ApplicationUser_3D8410FBA1701532D53558B4E07B366CC45F4901DA609FCE10D652D704EEDD3C.get_CarGame()\ r \ n   在PersonalProject.Controllers.MainPageController.GetUserInfo()中   C:\ Users \ Jack \ Desktop \ PostPersonalProject \ PersonalProject \ PersonalProject \ Controllers \ MainPageController.cs:line   32英寸字符串

1 个答案:

答案 0 :(得分:1)

由于以下原因,您正在获得例外:get_CarGame()

原始帖子中的代码与您的实际代码不匹配。

actual MainPageController.GetUserInfo中的某个地方,您正在尝试阅读ApplicationUser.CarGame。是的,这是延迟加载问题。

GetLoggedInUserInDB返回从ApplicationUser派生的代理类实例,并处理原始上下文。当GetUserInfo尝试获取CarGame属性值时,代理会尝试使用已处置的上下文从数据库读取它。结果,引发了异常。

如果您确实需要在CarGame中使用UserInfoModel

  • 要么如上所述关闭延迟加载,然后使用紧急加载;
  • 使用投影(即Select)作为原位UserInfoModel检索用户信息。在这种情况下,根本不需要使用GetLoggedInUserInDB方法。

无论如何,将LoggedUser附加到另一个上下文不是可行的方法。