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