1

我的控制器中有这段代码:

public class MyController : Controller
{
  private readonly IMyRepository myRepository;

  public MyController() : this(new MyRepository())
  {}

  public MyController(IMyRepository myRepository)
  {
    this.myRepository = myRepository;
  }

  public ActionResult Index()
  {
    return View(myRepository.GetData());
  }
}

MyRepository 使用 EF 进行数据操作。每次用户加载此页面时,MyRepository 实例都会创建。这意味着 EF 上下文正在创建并且 Fluent API 代码正在执行(OnModelCreating 方法)。

每次用户加载页面时是否有可能不创建 EF 上下文?

4

5 回答 5

7

MyRepository 使用 EF 进行数据操作。每次用户加载此页面时,MyRepository 实例都会创建。这意味着 EF 上下文正在创建并且 Fluent API 代码正在执行(OnModelCreating 方法)。

你错了。在 OnModelCreating 方法上放置一个断点。当您的应用程序加载时,此方法只会被命中一次。如果您重建项目,它将再次遇到断点,因为这会导致二进制 dll 重新加载到应用程序域中。但是,如果您让应用程序运行并两次点击控制器操作(中间没有重建),您将看到OnModelCreating第二次不会被点击。就像 Serg Rogovtsev 所说,EF 在 OnModelCreating 期间创建模型(即模式)后对其进行缓存。

我对Serg Rogovtsev 的回答的唯一反对意见是我永远不会创建 DbContext 的单例实例。相反,您应该为每个 HttpContext (也就是每个 Web 请求)使用一个实例。如果您将其用作单例,并且启用了并发,您最终会看到 DbConcurrencyExceptions 在您的应用程序中蔓延。使用 DI/IoC,并在请求响应周期的开始/结束时创建/处置 DbContext 实例。这是最好的做法。不要担心创建new MyDbContext()实例的开销。在第一次构建期间 EF 初始化(预热)之后,未来的构建将相当便宜。

于 2012-07-24T20:29:37.957 回答
2

要回答您的问题:您可以创建存储库的单例,或者您可以使用 DI 容器来为您保存单个实例。

但重点是:如果你在里面设置断点,OnModelCreating你会发现每个应用程序实例只调用一次。EntityFramework 使用非常有效的模型缓存。因此,您不必担心创建 EF 上下文会导致性能下降。

于 2012-07-24T18:18:41.527 回答
0

更改您的控制器,以便您以惰性方式创建存储库的实例。例如,您可以使用Lazy < T >类。

于 2012-07-24T18:14:31.063 回答
0

在性能方面,我更倾向于保留数据而不是上下文,EF 上下文经过优化以创建并释放池中的连接。http://www.sql-server-performance.com/2012/entity-framework-performance-optimization/上的其他一些 EF 性能方法

于 2012-07-24T18:21:39.530 回答
0

最佳做法是在检索/更新数据后处理 EF 上下文。

于 2012-07-24T18:26:11.213 回答