System.ObjectDisposedException:ObjectContext实例已被释放,不再可以

时间:2014-12-09 01:34:05

标签: c# asp.net-mvc asp.net-mvc-4

登录方式:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Login([Bind(Include = "Id,Mail,Pass")] LoginMember member)
    {
        if (!(ModelState.IsValidField("Mail") && ModelState.IsValidField("Pass")))
        {
            return View(login);
        }

        var areThere = db.LoginMember.Any(x => x.Mail == member.Mail && x.Sifre == member.Sifre);

        if (areThere)
        {
            var name = db.LoginMember.Where(x => x.Id == member.Id).Select(x => x.Name);

            Session["login"] = name;
            return RedirectToAction("Index", "Index");
        }
    }

此方法正在运行,会话正在创建“Session [”login“] = name;”然后“返回RedirectToAction(”索引“,”索引“);”。

索引视图:

@{
    Layout = null;
}

@Session["login"]

<html>Index</html>

当Index视图运行时,出现错误“System.ObjectDisposedException:ObjectContext实例已被释放,不能再用于需要连接的操作。”,有什么问题?

1 个答案:

答案 0 :(得分:3)

我相信你的问题就在这里......

var name = db.LoginMember.Where(x => x.Id == member.Id).Select(x => x.Name);

来自WhereSelect的返回值仍保留对ObjectContext的引用,请记住这些扩展方法是使用延迟执行实现的,查询在您枚举之前不会执行它。然后,当您将IEnumarable对象保存到会话变量然后从控制器的操作方法“返回”时,ObjectContext就会被收集,因为据说它不再需要了。因此,基本上一旦视图引擎呈现索引视图,您的会话变量就会持有一个被处置对象...因此当您尝试访问它时会出现异常。

要解决此问题,您需要“解析”Linq表达式。我建议使用FirstOrDefault,因为你只期待一个(并且只有一个)用户...

var user = db.LoginMember.FirstOrDefault(x => x.Id == member.Id);
var username = user != null ? user.Name : string.Empty;

以上更安全,您可以保证如果找不到用户FirstOrDefault将不会抛出异常