天天看點

EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言

上一篇我們簡單講述了在EF Core1.1中如何進行遷移,本文我們來講講EF Core1.1中那些不為人知的事,細摳細節,從我做起。

這個想必是我們最簡單的方式了吧,通過調用繼承自DbContext的類并且調用它的無參構造函數,同時我們需要謹記的時每當執行個體化時我們都需要将其釋放也就是将其執行個體包裹在Using中。如下:

接着通過重載OnConfiguring來配置EF Core上下文執行個體,如下。

【注意】:重載OnConfiguring和之前EF版本中的OnModelCreating建立模型不一樣,OnModelCreating建立模型上下文隻執行個體化一次,但是OnConfiguring每執行個體化一個上下文時都會被調用一次,是以OnConfiguring能充分利用上下文中的構造函數或者其他資料。

在EF 6.x中對于上下文有許多構造函數,例如連接配接字元串傳參,在EF Core 1.1中也是可以的如下:

EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言

在DbContext的構造函數中我們可以接受一個DbContextOptions對象,這個主要用在當在DI容器中建立DbContext執行個體時會用到,當然它也能被顯式調用,通過建立DbCOntextOptions對象來與上下文隔離,是以用它可以為每一個上下文的執行個體使用相同的options,如下:

EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言

看到這裡我們看到确确實實不再需要重載OnConfiguring,但是OnConfiguring将還是會被一直重載和調用,為什麼會這樣尼,因為我們在配置中注入上下文它會調用構造函數并同時來對OnConfiguring進行适當的調整。

我們隻要在DI容器中注冊上下文類型,然後它将被DI容器所解析,但是将上下文注冊到DI容器中我們就不用管了嗎,你還得注意到以下兩點。我們一般将其注入到DI容器中是這樣做的。

EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言

合情合理合法,但是為什麼不能如下這樣用尼

利用單例的形式注入難道就不行麼,如果你這樣做了,你就等着程式崩潰吧,因為上下文DbContext不是線程安全的,也就是說不能被注冊到單例來使用沒有額外的鎖。接着就是在将其注入到DI容器後,當我們使用時還是用Using來包裹,你别以為注入到DI容器中就萬事大吉它替你什麼都做了,DI容器不會替你自動處理,當然了,如果你隻是暫時在DI容器中使用的話,通常不會發生災難。是以我們需要謹記如下兩點。

(1)将上下文注入到DI容器中後,當使用DbContext依然還是用Using包括,因為DI容器不會自動将其釋放。

(2)DbContext是非線程安全的,即使是在DI容器中,也無非保證不出問題,大部分情況下是不會有問題的,不要擔心。

我們在DI中注冊一個DbContextOptions執行個體還是有點用,它隻會被建立一次并作為單例使用。比如我們可以初始化資料啊,如下

EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言

現在EFCoreContext上下文将會被DI容器解析,通過将DbContextOptions執行個體将被注入到它的構造函數中。這個_serviceProvider就是注入上下文的提供者,我們上述也說了可以初始化資料,如何初始化尼,來我們看看。在Startup.cs中有如下配置使用方法:

這個app有如下屬性:

EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言

發現什麼沒有,這個就是所有注入的服務的抽象屬性,我們将其轉換成EFCoreContext就可以在這個方法中初始化資料,我們看看。

EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言

上述我們介紹的都是非泛型的DbContextOptions對象,如下:

EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言

但是其參數中的DbContextOptions還有一個泛型版本,那麼泛型是用來幹嘛的了,我們先看如下例子:

EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言
EntityFramework Core 1.1是如何建立DbContext執行個體的呢?前言

看到什麼沒有,如果有多個上下文類型在DI容器中注冊時我們可以允許每個上下文的類型都依賴于自己的Options。當解析EFCoreContext1時将會導緻DbContextOptions<EFCoreContext1>會被注入,同理當解析EFCoreContext2時将導緻DbContextOptions<EFCoreContext2>會被注入。

通過AddDbContext文法糖來注冊DbContext和DbContextOptions執行個體。如下:

預設情況下将EFCoreContext作為scope進行注冊,将DbContextOptions作為單例進行注冊,你可更改将EFCoreContext作為單例注冊,上述我們已經讨論過這個問題了啊。好了到了這裡想必我們知道建立EF Core上下文執行個體的幾種方式了吧,我們概括為以下三點。

(1)直接調用上下文構造函數并重載OnConfiguring建立上下文執行個體。

(2)傳遞DbContextOptions到構造函數中建立上下文執行個體。

(3)通過DI容器來建立上下文執行個體。

使用DbContextOptionsBuilder來配置一個DbContext并最終構造一個DbContextOptions對象,這也能夠通過重載OnConfiguring方法或者通過構造options來傳遞到DbContext的構造函數中去,無論是通過無參構造函數還是通過DbContextOptions傳遞到上下文的構造函數中去,抑或是通過将DbContext注入到DI容器中去都是一樣的,都沒有什麼本質差別,隻不過通過DI簡便一點而且逼格比較高而已,沒有其他。

好了,本節我們對于EF Core 1.1中建立上下文的幾種方式都已叙述完畢,你是否已經Understand呢.

本文轉自Jeffcky部落格園部落格,原文連結:http://www.cnblogs.com/CreateMyself/p/6224141.html,如需轉載請自行聯系原作者

繼續閱讀