[英]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.