在ASP.NET MVC视图中解决"Dispose之后访问的DataContext"错误

Max*_*sky 2 c# asp.net datacontext asp.net-mvc linq-to-sql

我有一个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
            });
        }
    }
Run Code Online (Sandbox Code Playgroud)

该视图包含以下代码:

<%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>
<% } %>
Run Code Online (Sandbox Code Playgroud)

我正在访问item.PostTags,这是通过我的DataContext获得的.在这里,我基本上使用延迟加载,但是我收到一个错误:我的DataContext已经在列出那些PostTag时被处理掉了.

在处理DataContext之前如何加载这些数据?

RPM*_*984 6

两种选择:

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
            });
        }
Run Code Online (Sandbox Code Playgroud)

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

编辑

对不起 - 我以为你在使用Entity Framework,这里是L2SQL相当于"eager loading":

您需要使用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
            });
        }
Run Code Online (Sandbox Code Playgroud)