使用 DbContextOptionsBuilder 來指定連線字串與觀察 EF Core 產生的 SQL 指令
接續 上一篇 EF Core 討論文章 DbContext 在多執行緒環境下的運作情況 ,有些時候,當要使用 DbContext 來建立一個可以存取資料庫的 EF Core 的物件,想要能夠自行指定連線字串,可以在該繼承 DbContext 的類別建構函式內,傳入要使用的連線字串,並且於 OnConfiguring 方法內,使用該傳入的連線字串做為要連線到資料庫的依據;不過,這裡使用另外一個方式,那就是使用 DbContextOptionsBuilder 型別,產生一個這個物件,以便指定要使用的連線字串。
請按照底下的步驟來進行操作
建立練習專案
- 打開 Visual Studio 2019
- 點選 [建立新的專案] 按鈕
- 在 [建立新專案] 對話窗內,選擇 [主控台應用程式 (.NET Core)] 專案樣板
- 在 [設定新的專案] 對話窗內,於 [專案名稱] 欄位內輸入
efDbContextOptionsBuilder
- 點選 [建立] 按鈕,以便開始建立這個專案
加入 Entity Framework Core 要使用到的 NuGet 套件
- 滑鼠右擊專案內的 [相依性] 節點
- 選擇 [管理 NuGet 套件]
- 點選 [瀏覽] 標籤分頁頁次
- 在 [搜尋] 文字輸入盒內,輸入 [Microsoft.EntityFrameworkCore.SqlServer]
- 點選 [安裝] 按鈕以便安裝這個套件
- 在 [搜尋] 文字輸入盒內,輸入 [Microsoft.EntityFrameworkCore.Tools]
- 點選 [安裝] 按鈕以便安裝這個套件
使用反向工程來產生 Entity Framework 要用到的 Entity 模型相關類別
切換到 [套件管理器主控台] 視窗
若沒有看到 [套件管理器主控台] 視窗,點選功能表 [工具] > [NuGet 套件管理員] > [套件管理器主控台]
在 [套件管理器主控台] 輸入底下內容
因為都在同一個專案內,所以,這裡可以省略
StartupProject
&Project
這兩個參數,因此,底下的指令會更為精簡
Scaffold-DbContext "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=School" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -f
現在 Entity Model 相關資料已經建立完成
請觀察 [SchoolContext.cs] 檔案,這裡的 SchoolContext 類別繼承了 DbContext 類別,不過,這裡有兩個建構式,一個是預設建構函式,也就是沒有任何參數的建構式,另外一個建構式可以接收 [DbContextOptions] 這個型別的物件;另外,在 [OnConfiguring] 覆寫方法內,將會檢查傳入的 [DbContextOptionsBuilder] 物件的 [IsConfigured] 屬性是否為 真,用來確認是否已經指定了連線字串,若沒有指定的話,將會在這裡使用預設的本機 localDB 資料庫之連線字串。
public partial class SchoolContext : DbContext
{
public SchoolContext()
{
}
public SchoolContext(DbContextOptions<SchoolContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=School");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
. . .
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
因此,透過上面的解說,將會進行相關的程式開發與設計
請打開這個 [Program.cs] 檔案,完成底下的程式碼
static void Main(string[] args)
{
string connectionString = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=School";
DbContextOptions<SchoolContext> options = new DbContextOptionsBuilder<SchoolContext>()
.UseSqlServer(connectionString)
.Options;
using (var context = new SchoolContext(options))
{
Console.WriteLine($"取得 StudentGrade 第一筆紀錄");
var aStudentGrade = context.StudentGrade.FirstOrDefault();
Console.WriteLine($"{aStudentGrade.StudentId} 學生的 {aStudentGrade.CourseId} 課程的成績為 {aStudentGrade.Grade}");
}
}
從上面的程式碼中,可以看到首先建立了一個 connectionString 字串物件,該字串即是準備要用到的連線字串,緊接著建立一個 [DbContextOptions] 泛型型別物件,在該物件建立之後,便呼叫 [UseSqlServer] 方法,只是此次要 EF Core 使用指定的連線字串,連線到 SQL Server 服務上,最後,透過 [Options] 屬性,取得此次設定的相關內容。
如此,便可以建立 [SchoolContext] DbContext 物件,不過,需要在該建構函式內傳入剛剛產生的 [DbContextOptions] 物件,如此,一切準備工作都就緒了,便可以透過 [context] 變數來取得後端 SQL Server 內資料表的紀錄。
執行結果如下
取得 StudentGrade 第一筆紀錄
2 學生的 2021 課程的成績為 4.00
最後,要來觀察究竟 EF Core 產生了甚麼 SQL 指定到後端 SQL Server 內,此時,便可以透過 SSMS (SQL Server Management Studio) 這個工具來觀察,請打開此連結 SSMS ,下載與安裝這個工具。
安裝好之後,請找到 SQL Server Profilee 18 這個應用程式,並且打開與執行。
點選功能表 [檔案] > [新增追蹤] 選項
當 [連線至伺服器] 對話窗出現之後,請在 [伺服器名稱] 欄位內,輸入 (localdb)\.
內容
點選 [連線] 按鈕,連線到 SQL Server Express LocalDB 上
當出現 [連線屬性] 對話窗,點選 [執行按鈕]
現在可以重新執行剛剛建立的 [efDbContextOptionsBuilder] 專案;一旦執行完成之後,便可以看到底下的內容
從上面的 SQL Server Profiler 畫面中,可以看到此次將送出底下的 SQL指令到 SQL Server 內,而這個 SQL 指令是因為程式中執行了 context.StudentGrade.FirstOrDefault();
敘述, EF Core 根據這個 C# 敘述所產生出來的 SQL 指令。
SELECT TOP(1) [s].[EnrollmentID], [s].[CourseID], [s].[Grade], [s].[StudentID]
FROM [StudentGrade] AS [s]
沒有留言:
張貼留言