在视图中使用实体时已释放ObjectContext实例

时间:2015-07-26 03:55:09

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

有许多相关的问题,但没有一个解决了我的问题。我的目的是使用Razor PDF生成pdf。 所以我有一个控制器动作,其中包含;

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
   //some code
    </style>
  </head>

  <script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
  <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
  var socket = io();
  $('form').submit(function(){
    socket.emit('chat message', $('#m').val());
    $('#m').val('');
    return false;
  });
</script>

  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </body>
</html>

MyDbQuery与我正在使用的解决方案不同。我有这种方法:

var pdf = new PdfResult(null, "myView");
ViewBag.VrList = MyDbQuery.GetExpiredVL(DateTime.Today);
return pdf;

我的观点如下:

public static List<VLEntity> GetExpiredVL(DateTime ReportDate)
{
    using (MyDbContext db = new MyDbContext())
    {
        return db.VLEntity.Where(vl => vl.ValidTo.Month == ReportDate.Month && vl.ValidTo.Year == ReportDate.Year).ToList();
    }
}

当我调试时,我得到:

  

System.ObjectDisposedException:ObjectContext实例已被释放,不能再用于需要连接的操作。

我在这里发现的类似问题中说使用@foreach (var vrRow in ViewBag.VrList) { @vrRow.VEntity.VssId } 语句。但你可以在这里看到我已经使用过它了。我对ASP.NET和C#都很陌生,如果您能为此提出解决方案,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

在此代码中:

@foreach (var vrRow in ViewBag.VrList)
{
    @vrRow.VEntity.VssId
}

您正在访问navigation property VEntity。如果您不禁用延迟加载(默认情况下已启用),则在查询时不会从数据库加载此属性,但仅在访问属性时(通过proxy generation)。

在您的数据访问方法中,您执行db.VLEntity.[..].ToList(),但这只会实现从查询返回的VLEntity - 而不是其导航属性。

由于断开连接的场景(控制器中的操作方法首先运行,然后将其数据移至视图),因此在您访问导航属性时不再可访问上下文。

为此,您需要显式加载导航属性(与claim you did一样):

return db.VLEntity
         .Include(v => v.VEntity)
         .Where([..])
         .ToList();

现在,当视图访问列表的VEntity属性时也会实现,因此您的视图不再需要访问数据库。

你之前也说它有用,但是你可能只是没有访问任何导航属性。

相关:Best practises in MVC for not disposing the object context?How to solve the error The ObjectContext instance has been disposed and can no longer be used for operations that require a connection

替代方案是将DbContext保持更长时间(您不应该这样)并引入您在控制器中映射到的ViewModel。