簡體   English   中英

ASP.NET Boilerplate-“ ObjectContext實例已被處置”異常

[英]ASP.NET Boilerplate - “The ObjectContext instance has been disposed” exception

我正在嘗試使用ASP.NET Boilerplate處理我的項目,但我遇到了一個嚴重的問題。

我有2個模特:照片和評論:

public class Comment : Entity<int>
{
    [DataType(DataType.MultilineText)]
    public string Text { get; set; }
    public string Author { get; set; }

    public int ItemID { get; set; }
    public virtual Item Item { get; set; }
}

public class Item : Entity<int>
{
    public string Title { get; set; }

    public string Description { get; set; }

    public ItemSourceType SourceType { get; set; }

    public byte[] PhotoBytes { get; set; }

    public string Url { get; set; }

    public virtual ICollection<Comment> Comments { get; set; }

}

另外,我已經基於RepositoryBase<Item>創建了默認的OOB存儲庫,並且對Comment

當我嘗試獲得像這樣的商品時,存在問題:

    public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        Item item = _repoItems.Get(id.Value);
        if (item == null)
        {
            return HttpNotFound();
        }
        return View(item);
    }

當我調試此代碼時,我可以在Comments屬性中看到該item具有此異常。

我是否缺少ASP.NET Boilerplate的內容?

感謝您的幫助!

//編輯:完整的異常消息:

{"The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."}

我只是偶然發現了同樣的問題。 似乎是UnitOfWork實現為每個“ UnitOfWork”創建並布置了一個新的DbContext。

因此,要解決該特定問題,請嘗試注入“ IUnitOfWorkManager”並調用

public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        using(var uow = _unitOfWorkManager.Begin())
        {
            try
            {
                Item item = _repoItems.Get(id.Value);
                if (item == null)
                {
                    return HttpNotFound();
                }
                return View(item);
            }
            finally
            {
               uow.Complete()
            };
        }
    }

如果可行,請考慮在ApiController的構造函數中調用“ Begin()”,並在其“ Dispose()”替代中調用“ Complete()”。 希望有幫助!

否。問題很可能在您的存儲庫中,不幸的是您未包含其中的代碼。 如果我不得不猜測,我會說您在該存儲庫方法中使用的是以下內容:

using (var context = new ApplicationContext())
{
    // fetch something
}

您的Comments屬性是虛擬的,這意味着默認情況下,Entity Framework將延遲加載它,僅當您嘗試訪問該屬性時才向數據庫實際發出該查詢。 但是,到那時,您的上下文已被處置,因為存儲庫方法已完成其工作,並且您的上下文僅在using塊內可用。

有很多方法可以解決此問題。 您可以熱切地在using塊中加載注釋:

return context.Items.Include("Comments").Find(id);

但是,這確實可以解決問題。 您可以做的最好的事情就是不使用using 理想情況下,對於每個請求,您的上下文應實例化一次,並且只能實例化一次。 最簡單的方法是使用依賴項注入容器,並向您的存儲庫中添加一個接受上下文的構造函數:

public class MyAwesomeRepository
{
    private readonly ApplicationContext context;

    public MyAwesomeRepository(ApplicationContext context)
    {
        this.context = context;
    }
}

DI容器的配置將根據您選擇的配置而有所不同,但是通常,您需要確保將上下文類綁定到請求范圍。

我在ASP.NET Boilerplate中遇到了類似的問題,並發現只有當您根據接口和類的命名約定命名該接口和類時,此框架才能正確實現所有DI魔術。 您可以通過某種方式手動進行操作,但是您必須深入了解ABP架構,而不是想要的。

@ChrisPratt發布的鏈接(請參閱答案中的評論)說:

命名約定在這里非常重要。 例如,您可以將PersonAppService的名稱更改為MyPersonAppService或其他包含“ PersonAppService”后綴的名稱,因為IPersonAppService具有此后綴。 但是您不能將服務命名為PeopleService。 如果執行此操作,則不會自動為IPersonAppService注冊(它已注冊到DI框架,但已通過自注冊,而不是通過接口注冊),因此,如果需要,應手動注冊。

就我而言,我有一個名為ProductService的服務,該服務實現了IProductAppService接口。 在我將服務重命名為ProductAppService之前,它因ObjectDisposedException異常而失敗。

我認為OP仍然沒有這個問題,但是希望它將為像我一樣在ABP方面苦苦掙扎的人們節省幾個小時。 :-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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