1

我有我的控制器验证码:ASP.NET MVC + EF性能

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上下文?

+1

你确定吗?您是否真的衡量了性能影响? – 2012-07-24 18:20:30

+0

http://blog.oneunicorn.com/2012/04/21/code-first-building-blocks/ – 2012-07-24 18:22:58

回答

7

MyRepository使用EF进行数据操作。每次用户加载这个 正在创建的MyRepository页面实例。这意味着EF上下文是 创建和Fluent API代码正在执行(OnModelCreating方法)。

你错了。在OnModelCreating方法上放置一个断点。这个方法只会在您的应用程序加载时触及一次。如果重建项目,它会再次触发断点,因为这会导致二进制DLL被重新加载到应用程序域中。但是,如果让应用程序继续运行并且两次触发控制器操作(无需重建),您将看到OnModelCreating不会再次出现。 Like Serg Rogovtsev says,EF在OnModelCreating期间创建模型(表示模式)之后缓存模型。

唯一的异议我必须Serg Rogovtsev's answer是我永远不会创建DbContext的单例实例。相反,你应该每个HttpContext使用一个实例(也就是每个Web请求)。如果您将它作为单例使用,并且您已启用并发,则最终会在您的应用程序中看到DbConcurrencyExceptions。使用DI/IoC,并在请求响应周期的开始/结束时创建/处理DbContext实例。这是最佳做法。不要担心创建new MyDbContext()实例的开销。 EF在第一次施工期间初始化(预热)后,未来的施工将相当便宜。

+0

关于在每个应用程序中使用DbContext的一个实例的并发性问题(以及其他一些含义),你是对的(我错了,没有提及它)。 – 2012-07-24 20:35:37

+0

我完全同意。除了单例作用域上下文的并发性错误之外,这种方法还存在一个主要的性能问题。 EF枚举最重要操作上的所有跟踪实体,如果您使用的是单例上下文,则可能不清除此跟踪的集合。这意味着您的应用在运行时间越长越慢。请参阅http://blog.staticvoid.co.nz/2012/05/entityframework-performance-and.html为什么EF在大背景下速度很慢 – 2012-07-24 21:36:29

+0

另外,从我的测试中,DbContext的创建速度非常快(当您多次执行时它的速度如此之快,它甚至不应该记录任何与实际操作相比的性能指标,请参阅http://blog.staticvoid.co.nz/2012/03/entity-framework-comparative。 html有关EF运行速度的更多详细信息 – 2012-07-24 21:37:02

0

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

+1

听起来像一个懒惰的方法。 – Har 2012-07-24 18:16:05

+1

哈哈,有趣:-) – Maarten 2012-07-24 18:16:58

+0

+1对一个荒谬的评论很好的回应。 – Har 2012-07-24 18:18:04

2

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

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

0

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