簡體   English   中英

DbContext 已被釋放

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM