【问题标题】:Getting around "DataContext accessed after Dispose" error in ASP.NET MVC View解决 ASP.NET MVC 视图中的“Dispose 后访问的 DataContext”错误
【发布时间】:2010-11-25 00:27:10
【问题描述】:

我有一个如下所示的 ASP.NET MVC 2 操作:

public ActionResult Index()
    {
        using(var db = new MyDataContext())
        {
            var welcomeSnippet = "test";
            var articles = db.Posts.Where(p => p.DateOfPublish <= DateTime.Now).Take(5).ToList();
            return View(new HomeViewModel()
            {
                Articles = articles,
                WelcomeSnippet = welcomeSnippet
            });
        }
    }

视图包含以下代码:

<%foreach (var item in Model.Articles)
{%>
     <div class="article" id="<%=item.PostID %>">
          <!-- some properties -->
          <div class="tags">tags: <i><%foreach (var tag in item.PostTags.ToList())
                                        { %><%=Html.Encode(tag.Tag.TagName.Trim())%> <%} %></i>
          </div>
     </div>
<% } %>

我正在访问item.PostTags,它是通过我的DataContext 获得的。在这里,我本质上是在使用延迟加载,但我遇到了一个错误:在列出这些 PostTag 时,我的 DataContext 已经被释放了。

如何在处理我的 DataContext 之前加载此类数据?

【问题讨论】:

标签: c# asp.net asp.net-mvc linq-to-sql datacontext


【解决方案1】:

两种选择:

1) 手动处理 DC(例如 Global.asax 中的 Application_EndRequest)

2) 在控制器中预加载item.Tags

using(var db = new MyDataContext())
        {
            var welcomeSnippet = "test";
            var articles = db.Posts.Include("PostTags").Where(p => p.DateOfPublish <= DateTime.Now).Take(5).ToList();

            return View(new HomeViewModel()
            {
                Articles = articles,
                WelcomeSnippet = welcomeSnippet
            });
        }

我会选择选项 2,因为选项 1 在不使用 DI 容器的情况下是有风险的。 (你显然没有使用)。

编辑

抱歉 - 我以为您使用的是实体框架,这里是 L2SQL 等效的“急切加载”:

您需要使用 DataLoadOptions

using(var db = new MyDataContext())
        {
            var dataLoadOptions = new DataLoadOptions();
            dataLoadOptions.LoadWith<Post>(x => x.PostTags);
            db.LoadOptions = dataLoadOptions;

            var welcomeSnippet = "test";
            var articles = db.Posts.Where(p => p.DateOfPublish <= DateTime.Now).Take(5).ToList();

            return View(new HomeViewModel()
            {
                Articles = articles,
                WelcomeSnippet = welcomeSnippet
            });
        }

【讨论】:

  • 所以对于我需要预先加载的每个属性,我只需要:`.Include("PropertyName")?伟大的!这解决了我的短期需求,但我一定会研究依赖注入。
  • 嗯....Include() 没有出现在 Intellisense 中。您能否将我指向一个引用它的 MSDN 页面,以便我可以确保我没有做错什么?
  • 哦,废话,等等——你使用的是 L2SQL,我以为你使用的是实体框架。我的错。 Include 是特定于 EF 的。将更新我的答案。
  • 没问题,我已经找到了解决方法:singingeels.com/Blogs/Nullable/2008/10/27/…。当我升级到 .NET 4 时,我可能会切换到:damieng.com/blog/2010/05/21/…weblogs.asp.net/ricardoperes/archive/2010/11/06/…
  • 是的 - 这是我在我编辑的答案中输入的内容。 :) 建议 - 下一个项目,使用 EF。 L2SQL 基本上已经过时了。 (无论如何在 MS 眼中)
猜你喜欢
  • 1970-01-01
  • 2011-05-18
  • 1970-01-01
  • 1970-01-01
  • 2012-05-20
  • 2011-03-31
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多