[英]DbContext has been disposed
我使用 ASP.NET MVC 4 和 SQL Server 2008 开发了一个 web 应用程序,我创建了 ContextManager class 在所有页面中只有一个数据库上下文。
public static class ContextManager
{
public static HotelContext Current
{
get
{
var key = "Hotel_" + HttpContext.Current.GetHashCode().ToString("x")
+ Thread.CurrentContext.ContextID.ToString();
var context = HttpContext.Current.Items[key] as HotelContext;
if (context == null)
{
context = new HotelContext();
HttpContext.Current.Items[key] = context;
}
return context;
}
}
}
它在大多数页面中都能正常工作,但在注册页面中出现了问题,我的上下文因以下错误而被废除:
操作无法完成,因为 DbContext 已被释放。
public ActionResult Register ( RegisterModel model )
{
if ( ModelState.IsValid )
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount( model.UserName, model.Password,
new
{
Email = model.Email,
IsActive = true,
Contact_Id = Contact.Unknown.Id
} );
//Add Contact for this User.
var contact = new Contact { Firstname = model.FirstName, LastName = model.Lastname };
_db.Contacts.Add( contact );
var user = _db.Users.First( u => u.Username == model.UserName );
user.Contact = contact;
_db.SaveChanges();
WebSecurity.Login( model.UserName, model.Password );
在行_db.Contacts.Add( contact );
我得到了例外。
但是不通过更改使用 ContextManager
HotelContext _db = ContextManager.Current;
进入:
HotelContext _db = new HotelContext();
问题解决了。 但是我需要使用我自己的 ContextManager。 问题是什么?
您的上下文已放置在其他地方(不在您显示的代码中),因此基本上,当您从Register
操作访问它时,它将引发异常。
实际上,您不应该使用静态单例来访问您的上下文。 为每个请求实例化一个新的DbContext
实例 。 请参阅C#在多线程服务器中使用Entity Framework
就我而言,我的GetAll方法未在lambda表达式中的where子句之后调用ToList()方法。 使用ToList()之后,我的问题解决了。
Where(x => x.IsActive).ToList();
您可能正在注册视图中“延迟加载” User
的导航属性。 在将其发送到视图之前,请确保通过使用DbSet
上的Include
方法将其Include
DbSet
:
_db.Users.Include(u => u.PropertyToInclude);
同样,共享具有静态属性的DbContext
可能会有意外的副作用。
我曾经有过同样的问题。 我按照上面所说的解决了这个问题。 实例化上下文的新实例。
尝试使用此:
using (HotelContextProductStoreDB = new ProductStoreEntities())
{
//your code
}
这样,每次使用代码时都会创建一个新实例,并且不会释放上下文。
为什么要覆盖Dispose(bool)?
public partial class HotelContext : DbContext
{
public bool IsDisposed { get; set; }
protected override void Dispose(bool disposing)
{
IsDisposed = true;
base.Dispose(disposing);
}
}
然后,检查IsDisposed
public static class ContextManager
{
public static HotelContext Current
{
get
{
var key = "Hotel_" + HttpContext.Current.GetHashCode().ToString("x")
+ Thread.CurrentContext.ContextID.ToString();
var context = HttpContext.Current.Items[key] as HotelContext;
if (context == null || context.IsDisposed)
{
context = new HotelContext();
HttpContext.Current.Items[key] = context;
}
return context;
}
}
}
也许可以选择。
如果您需要检查您的 DbContext 是否仍然有效(未处置),则需要重新创建 DbContext:请参阅有关为 DbContext 部分类定义 IsDisposed() 扩展方法的答案https://stackoverflow.com/a/74894375 /1518501
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.