【问题标题】:Entity Framework - How should I instance my "Entities" object实体框架 - 我应该如何实例化我的“实体”对象
【发布时间】:2009-09-09 18:36:08
【问题描述】:

我是 Entity Framework 和 ASP.Net MVC 的新手,主要从教程中学习,对任何一个都没有深入了解。 (我确实有 .Net 2.0、ADO.Net 和 WebForms 方面的经验)

我目前的疑问来自我实例化我的实体对象的方式。

基本上我在我的控制器中这样做:

public class PostsController : Controller {

    private NorthWindEntities db = new NorthWindEntities();

    public ActionResult Index() {
            // Use the db object here, never explicitly Close/Dispose it
    }
}

我之所以这样做,是因为我在一些 MSDN 博客中发现它对我来说似乎足够权威,我认为这是一种正确的方法。
但是,我对此感到非常不安。虽然它为我节省了很多代码,但我已经习惯了:

using (NorthWindEntities db = new NorthWindEntities() {
}

在每个需要连接的方法中,如果该方法调用其他需要它的方法,它会将 db 作为参数传递给它们。这就是在 Linq-to-SQL 存在之前我对连接对象所做的一切。

让我感到不安的另一件事是 NorthWindEntities 实现了 IDisposable,按照惯例,这意味着我应该将其称为 Dispose() 方法,而我没有。

您对此有何看法?
像我一样实例化实体对象是否正确?它是否应该通过为每个查询打开和关闭它们来处理其连接?
或者我应该使用 using() 子句显式处理它?

谢谢!

【问题讨论】:

    标签: entity-framework dispose connection


    【解决方案1】:

    Controller 本身实现 IDisposable。因此,您可以重写 Dispose 并处置您在实例化控制器时初始化的任何内容(如对象上下文)。

    控制器只存在一个请求。因此,在一个动作中使用 using 并为整个控制器拥有一个对象上下文是完全相同的上下文数量:1.

    这两种方法的最大区别在于,动作将在视图呈现之前完成。因此,如果您在操作内的 using 语句中创建 ObjectContext,则 ObjectContext 将在视图呈现之前被释放。因此,您最好在操作完成之前从上下文中阅读所需的任何内容。如果您传递给视图的模型是一些惰性列表,例如 IQueryable,您将在视图呈现之前释放上下文,当视图尝试枚举 IQueryable 时会导致异常。

    相比之下,如果你在Controller初始化的时候初始化ObjectContext(或者写惰性初始化代码导致它在action运行时被初始化)并在Controller.Dispose中dispose ObjectContext,那么上下文仍然是渲染视图时左右。在这种情况下,将 IQueryable 传递给视图是安全的。 Controller 将在视图渲染后不久被释放。

    最后,如果我没有指出让您的控制器完全了解实体框架可能是一个坏主意,那我就失职了。考虑为您的模型和存储库模式使用单独的程序集,以使控制器与模型对话。谷歌搜索会出现很多。

    【讨论】:

    • 好的,有道理。现在,问题是……我做错了吗?我真的需要处理实体对象吗?如果我不这样做会怎样?我会“泄露”到 SQL Server 的连接吗?
    • ObjectContext.Dispose 并没有做太多(参见反射器)。但可以合理地假设这可能会发生变化并且您应该将其丢弃。
    【解决方案2】:

    您在这里提出了一个很好的观点。 ObjectContext 应该存在多久?所有模式和实践书籍(如 Dino Esposito 的 Microsoft-NET-Architecting-Applications)都告诉您 DataContext 不能存在很长时间,也不应该被缓存。

    我只是想知道,在您的情况下,为什么没有一个 ControllerBase 类(我不知道 MVC 实现,所以请耐心等待),其中 ObjectContext 为所有控制器启动一次。尤其是Identity Map Pattern,它已经由实体框架实现。即使您需要调用另一个控制器作为您的 PostsController,它仍然可以使用相同的 Context 并提高性能。

    【讨论】:

      猜你喜欢
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-19
      相关资源
      最近更新 更多