C# DbContext 已被释放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18635508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
DbContext has been disposed
提问by Ali Esfahani
I developed a web application with ASP.NET MVC 4 and SQL Server 2008, I create ContextManager class to have only one database context in all pages.
我使用 ASP.NET MVC 4 和 SQL Server 2008 开发了一个 Web 应用程序,我创建了 ContextManager 类以在所有页面中只有一个数据库上下文。
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;
}
}
}
It works properly in most of the pages, but in registration page something goes wrong and my context gone deposed with following error:
它在大多数页面中都能正常工作,但在注册页面中出现问题,我的上下文因以下错误而被废止:
The operation cannot be completed because the DbContext has been disposed.
操作无法完成,因为 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 );
at the line _db.Contacts.Add( contact );
I got the exception.
在这条线上_db.Contacts.Add( contact );
我得到了例外。
But without using ContextManager by changing
但不通过更改使用 ContextManager
HotelContext _db = ContextManager.Current;
into:
进入:
HotelContext _db = new HotelContext();
the problem was solved. But I need to use my own ContextManager. What is the problem?
问题解决了。但我需要使用我自己的 ContextManager。问题是什么?
采纳答案by ken2k
Your context has been disposed somewhere else (not in the code you've shown), so basically when you access it from your Register
action, it throws the exception.
您的上下文已被处理到其他地方(不在您显示的代码中),因此基本上当您从Register
操作中访问它时,它会引发异常。
Actually, you shouldn't use a static singleton to access to your context. Do instantiate a new DbContext
instance for each request. See c# working with Entity Framework in a multi threaded server
实际上,您不应该使用静态单例来访问您的上下文。为每个请求实例化一个新DbContext
实例。请参阅在多线程服务器中使用实体框架的 c#
回答by Henk Mollema
You are probably 'lazy-loading' a navigation property of User
in your registration view. Make sure you include it by using the Include
method on your DbSet
before sending it to the view:
您可能正在“延迟加载”User
注册视图中的导航属性。在将它发送到视图之前,请确保使用Include
您的方法包含它DbSet
:
_db.Users.Include(u => u.PropertyToInclude);
Also, sharing DbContext
s with a static property may have unexpected side effects.
此外,DbContext
与静态属性共享s 可能会产生意想不到的副作用。
回答by Dhanik Lal Sahni
In my case, my GetAll method was not calling ToList() method after where clause in lambda expression. After using ToList() my problem was solved.
就我而言,我的 GetAll 方法没有在 lambda 表达式中的 where 子句之后调用 ToList() 方法。使用 ToList() 后,我的问题解决了。
Where(x => x.IsActive).ToList();
回答by GreatNews
I used to have the same problem. I solved it doing as it was said above. Instantiate a new instance of your context.
我曾经有同样的问题。我按照上面说的那样解决了它。实例化上下文的新实例。
Try using this:
尝试使用这个:
using (HotelContextProductStoreDB = new ProductStoreEntities())
{
//your code
}
This way it'll be created a new instance everytime you use your code and your context will not be disposed.
这样,每次使用代码时都会创建一个新实例,并且不会处理上下文。
回答by antonio
Why override the Dispose(bool)?
为什么要覆盖 Dispose(bool)?
public partial class HotelContext : DbContext
{
public bool IsDisposed { get; set; }
protected override void Dispose(bool disposing)
{
IsDisposed = true;
base.Dispose(disposing);
}
}
And, then check IsDisposed
然后检查 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;
}
}
}
Maybe, can be an option.
也许,可以是一种选择。