为什么"Dispose"工作,而不是"使用(var db = new DataContext())"?

ECH*_*ECH 9 c# asp.net asp.net-mvc razor

我正在创建一个由主题组成的论坛,这些主题由消息组成.

当我尝试在我的控制器中实现主题视图时:

public ActionResult Topic(int id) //Topic Id
{
    using (var db = new DataContext())
    {
        var topic = db.Topics.Include("Messages").Include("Messages.CreatedBy").Include("CreatedBy").FirstOrDefault(x => x.Id == id);

        //include the messages for each topic, and when they were created so that the last message can be displayed on the topic page
        return topic != null ? View(topic) : View();
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试查看主题页面时收到此错误:

ObjectDisposedException未被用户代码处理

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

该错误似乎并不特定于某一行,因为当我删除有问题的行时,早先出现相同的错误.

我用以下方法解决了这个问题:

DataContext db = new DataContext();
Run Code Online (Sandbox Code Playgroud)

在控制器的开头和:

protected override void Dispose(bool disposing)
{
    db.Dispose();             
    base.Dispose(disposing);
}
Run Code Online (Sandbox Code Playgroud)

最后(并using取出)

虽然这有效,但我很好奇为什么"使用"不起作用,而且我真的很高兴在整个控制器中打开连接,并在最后手动处理它.

Dis*_*ile 7

您的任何实体是否启用了延迟加载?看起来有些查询在您的视图中被执行,但是您在执行它们之前处理它们(因此错误说它已经被处理掉了).如果将处理放在控制器Dispose方法中,视图将在处理控制器和上下文之前执行.

我建议安装Glimpse.Mvc5和Glimpse.EF6软件包.配置glimpse后,您可以看到在页面中执行的每个查询.您可能会惊讶地看到一些您不想要执行的其他查询.这就是我不建议您直接在视图中使用实体的原因.


ECH*_*ECH 1

这是延迟加载的问题,所以感谢您指出正确的方向@Dismissile

一旦我使用“.Include”加载主题的每个虚拟属性,它就工作得很好:

var topic = db.Topics.Include("Messages").Include("Messages.CreatedBy").Include("CreatedBy").Include("Forum").Include("DeletedBy").FirstOrDefault(x => x.Id == id);
Run Code Online (Sandbox Code Playgroud)

我想如果没有我说抱歉,任何人都不可能知道我宣布哪些财产为虚拟财产!

顺便说一句,它之前在我在调试模式下检查属性时有效,因为必须加载每个属性才能检查它