【问题标题】:DbContext has been disposed, does not make any senseDbContext 已经被释放,没有任何意义
【发布时间】:2015-02-12 17:58:35
【问题描述】:

我正在创建一个 C# Web 应用程序,我可以在其中添加公司以及公司的分支机构所在的位置。一家公司可以有多个地点分支机构。对于一个地点,可能有几家公司。所以CompaniesTerritory之间的关系是Many-Many

这是我目前的公司模型,

public class CompanyModel
{

    [HiddenInput(DisplayValue = false)]
    public long CompanyId { get; set; }

    [Display(Name = "Company Name")]
    [Required(ErrorMessage = "* required")]
    public string CompanyName { get; set; }

    [Display(Name = "Phone Number")]
    [Required(ErrorMessage = "* required")]
    [RegularExpression(@"\d*", ErrorMessage = "Not a valid phone number")]
    public string PhoneNo { get; set; }


    [Display(Name = "Post Code List", Prompt = "eg. BA5, BS16")]
    public string PostCodeList { get; set; }
}

它有一个文本框,可以接受逗号分隔的字符串。所以我使用foreach对其进行迭代以将其添加到表中,

            foreach (var s in company.PostCodeList.Split(','))
            {
                AddPostCode(s, company.CompanyId);
            }

AddPostcode 在哪里,

    public void AddPostCode(string postCode, long companyId)
    {
        using (var db = new BoilerServicingDbContext())
        {
            //Does post code exist
            var p = db.Territories.FirstOrDefault(x => x.PostCodePrefix == postCode);

            //if not create
            if (p == null)
            {
                p = new Territory
                {
                    PostCodePrefix = postCode
                };
                db.Territories.Add(p);
            }
            //get the company
            var c = db.Companies.First(x => x.Id == companyId);

            //add post code
            c.Territories.Add(p);

            //save
            db.SaveChanges();
        }
    }

现在我收到以下错误,

操作无法完成,因为 DbContext 已被释放。

说明:在执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详情:System.InvalidOperationException:操作无法完成,因为 DbContext 已被释放。

异常详细信息:System.InvalidOperationException:序列不包含任何元素

Source Error:

Line 16:         </thead>
Line 17:         <tbody>
Line 18:         @foreach (var a in Model)
Line 19:             {
Line 20:                 <tr>

Source File: c:\Source\LSP.HEA.BoilerServicing\Main\LSP.HEA.BoilerServicing.Web\Views\Companies\Index.cshtml
Line: 18 

【问题讨论】:

标签: c# entity-framework asp.net-mvc-3


【解决方案1】:

发生这种情况是因为您一直在等待视图呈现以迭代由 EF 查询生成的集合,并且此时上下文已被释放。

在访问集合之前,EF 不会实际运行 SQL 查询,因此您需要强制它在 DbContext 仍处于活动状态时拉取数据并填充集合。

对此的简单解决方案是使用ToList(),这会导致 EF 立即检索数据。

例如,而不是:

return View(mycollection);

试试:

return View(mycollection.ToList());

【讨论】:

  • 无论如何,在您的上下文中使用using 通常也是一个坏主意。您的上下文应根据请求进行实例化。比这更频繁,您很容易遇到这样的问题,或者被告知您要保存的对象或某些相关对象属于另一个上下文。
  • 另外,@Alan,OP 需要在 AddPostCode 方法中调用 .ToList,而不是在返回视图时调用。否则,同样的问题。上下文已被释放。
  • @ChrisPratt 我假设 OP 的问题实际上出在其他地方,因为我将 AddPostcode() 方法作为自包含(无效)函数阅读。真的需要查看更多代码才能给出正确的答案。我完全同意第一点——我通常使用 OwinContext 来保存 DbContext,但这是在默认情况下引入 OWIN 的 MVC5 项目中。
  • OwinContext 有效,而且微软实际上是用它来解决Identity 中的依赖关系,所以它有点带有官方的认可印章。不过,这对我来说感觉是错误的。我更喜欢为此目的使用真正的 DI 容器,无论应用程序是否支持 OWIN,它都可以工作。
  • 艾伦,谢谢您的回复。老实说,你说的大部分我都听不懂。我对 C# 和 MVC 真的很陌生,这是我的第一个应用程序,我没有模型、视图和控制器的背景,更不用说了解它们是如何工作的。我使用您的建议在使用查询的方法中使用 ToList。它工作得很棒。谢谢!
猜你喜欢
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
  • 1970-01-01
  • 1970-01-01
  • 2014-11-23
相关资源
最近更新 更多