2013-03-19 37 views
2

我已阅读过这里的其他类似帖子,但仍不清楚。我希望没有人能够重新唤醒某个主题,而不是诅咒某些事物并希望得到回应。MVC实体框架 - 处理DbContext的实例?

问题是何时处置DbContext。 这里是在我的MVC应用

 public ActionResult Index() 
     { 
      using (var db = new TheCurve.Models.TheCurveDb()) 
      { 
       var result = db.GetTopArticles().ToList(); 
       return View(result); 
      } 

     } 

在这个例子中一个控制器的一个例子,作为的DbContext已被释放,由于使用块的剃刀视图抛出异常。

如果我不处理DbContext,当Razor视图试图访问模型上的属性(例如这段代码)时,会抛出错误“已存在与此命令关联的打开的数据读取器”。

var type = Model.ArticleType.Type; 
    switch (type) 
    { 
     case "Example": 
      defaultTitleImage = "Content/themes/base/images/example.png"; 
      break; 

     case "Download": 
      defaultTitleImage = "Content/themes/base/images/download.png"; 
      break; 

     case "Link": 
      defaultTitleImage = "Content/themes/base/images/link.png"; 
      break; 

     case "Article": 
      defaultTitleImage = "Content/themes/base/images/article.png"; 
      break; 

    } 

我知道DbContext检索数据后关闭连接,但这是否意味着它不需要处理?

非常感谢

- 编辑

局部视图显示的文章概述。

@model TheCurve.Models.Article 


@{ 
    //Shorten description for Article overview 
    var strDescription = Model.Description.Length > 250 ? Model.Description.Substring(0, 250) + "..." : Model.Description + "..."; 

    //Decide which image to show on overview. 
    string defaultTitleImage = null; 
    if (Model.TitleImage == null) 
    { 
     var type = Model.ArticleType.Type; 
     switch (type) 
     { 
      case "Example": 
       defaultTitleImage = "Content/themes/base/images/example.png"; 
       break; 

      case "Download": 
       defaultTitleImage = "Content/themes/base/images/download.png"; 
       break; 

      case "Link": 
       defaultTitleImage = "Content/themes/base/images/link.png"; 
       break; 

      case "Article": 
       defaultTitleImage = "Content/themes/base/images/article.png"; 
       break; 

     } 

    } 
    else 
    { 
     defaultTitleImage = Model.TitleImage; 
    } 

} 


<article class="clear-fix"> 

<div class="float-left"> 
    <img src="@defaultTitleImage" alt="The Curve - Article Type"/> 
</div> 
<div class="float-left articleoverview"> 
    @Html.ActionLink(Model.Title.TrimStart(), "Details","Code", new {articleId = Model.Id}, null) 
    <p>@strDescription</p> 
    <p><i>By @Model.Author On @Model.DateCreated.ToString("dd/MM/yyyy")</i></p> 

</div> 
</article> 

这是使用上述部分的剃刀视图。

@model IEnumerable<TheCurve.Models.Article> 
@{ 
    ViewBag.Title = "Code Samples & Technology Blog"; 
} 
    <section> 
     <h3>Currently Viewing Most Recent Entries</h3> 
     @foreach (var item in Model) 
     { 
      @Html.Partial("_ArticleOverview", item) 
     } 
    </section> 
+0

看起来您需要在原始查询中包含导航属性,以允许通过Razor脚本引用它。你可以发布你的模型,以获得更好的信息吗? – WestDiscGolf 2013-03-19 09:47:35

+0

您应该重写控制器中的Dispose方法,并在那里处理上下文。 – vmeln 2013-03-19 09:49:19

+0

有一点让我有所不同,我忘了补充。开放数据阅读器错误将在局部视图中出现。我将在上面添加部分视图和视图。 – James 2013-03-19 09:59:53

回答

0

我在找的答案是DbContext应该总是在使用块中。为了防止在访问需要使用.ToList或.ToArray实现IEnumerable的对象时丢弃有关DbContext的错误。

解决方案的其他部分实际上是由von推荐使用平面模型来辅助的。

0

如果你用这个连接到SQL服务器(我假设是这样),然后在你的连接字符串中添加MultipleActiveResultsets = true。这允许多个开放的数据读取器连接到SQL服务器。

有关更多信息,请参阅this