前幾天被詢問 WinForm 在 .NET 5 能否使用 Entity Framework,從微軟提供的資料來說,只要安裝 EF 6.3 以上的版本就可以運行在 .NET Core 3 與最新的.NET 5 /.NET 6 上面, 雖說是可以運行,但開發的過程中就無法使用 Visual Studio 中的 ADO.NET 實體資料模型
功能,來自動產生資料庫模型。會出現專案的目標 Framework 不包含 Entity Framework 執行階段組件。請在專案屬性頁面中,檢視目標Framework資訊。
這樣的錯誤訊息。
變成 .NET Core 3 以上的版本,雖然可讀edmx
、可讀context
,但是不能幫你產模型,如果不想自己手動寫的話,微軟有提供一個範例程式,大概的意思是,在方案中開了一個 NET Core 的專案後,再加入一個 NET Framework 專案,用來使用ADO.NET 實體資料模型
產 Model ,讓 NET Core 的專案參考產出後的 Model 就可以了。
雖然我沒寫過 Windows Form ,不過資料存取這方面在 .NET 是大同小異,本文的方法在 .NET Core 3、 .NET 5 與 .NET 6 都是一樣的,這邊我用 .NET 6 建立一個 WinForms 專案來示範,已經知道如何使用 ADO.NET 實體資料模型
的同學可以直接跳到在 NET 6 專案中使用 NuGet 安裝 EntityFramework小節
內容目錄
使用 ADO.NET 實體資料模型
並且在方案總管中,對方案按 右鍵 > 加入 > 新增專案
這邊我選擇建立一個.NET Framework的類別庫
按下一步之後,可以看到 .NET Framework 的版本是 4.7.2,最後按建立
建立完之後,可以看到專案中只有一個 Class.cs 檔,這個檔案我們用不到,可以直接刪除。
接下來就是使用 ADO.NET 實體資料模型
,這裡對 ClassLibrary1 按右鍵
> 加入
> 新增項目
。點選左邊的資料
後點選ADO.NET 實體資料模型
,輸入名稱後按右下角的新增
這裡我選來自資料庫的EF Designer
,再按下一步
會出現選擇資料庫連線的畫面,選擇完按下一步
就可以選擇 EF 的版本。
若沒有出現資料庫連線選項,可以按新增連接
,依你的資料庫來源選擇資料來源產生相對應的連線字串,詳細內容可以跳至新增資料庫連結。
選擇 Entity Framework 6.x 版本
依需求選擇要使用到的物件,這邊我全選資料表
使用T4自動產生程式碼功能時,都會跳出這類安全提示,詢問是否確定執行,這邊選確定
執行完成後可以看到我們的 edmx
與資料庫的資料表所對應的物件 User.cs
已經在專案中
新增資料庫連結
選擇資料來源後按繼續
輸入你的資料庫伺服器名稱,並選擇登入方式後按左下角的測試連結
,測試成功後就可以選擇連到我的TestDB
資料庫了,完成後按確定
就會回到選擇資料庫連線
的畫面
在 .NET 6 專案中使用 NuGet 安裝 EntityFramework
一樣我們對專案按右鍵
> 管理 NuGet 套件
選擇 瀏覽
> 輸入搜尋關鍵字 > 選擇 EntityFramework
最新版本來安裝
,這邊我安裝的最新版本是 6.4.4
安裝時會詢問是否同意安裝相關套件,這邊點選同意
並同意授權條款
讓 .NET 6 專案參考生成資料模型
現在讓我們修改 .NET 6 的專案檔 .csproj
檔,使之參考 ClassLibrary1
資料夾中生成的物件模型,為該 .NET 6 專案的檔案。因為 .NET Core 3 以上的版本參考edmx
檔時,需要手動更改參數,這邊就無法使用 Visual Studio 的加入專案參考功能。對專案按右鍵,選擇編輯專案檔
應該會出現這樣的畫面
接著在<Project></Project>
裡面插入以下程式碼,Compile
的意思是該專案編譯時,要將Include
路徑中的檔案,Link
為當前專案指定路徑中的檔案,而.edmx
檔需要使用EntityDeploy
來進行特殊的編譯(詳細資料)。
<ItemGroup>
<EntityDeploy Include="..\ClassLibrary1\Model1.edmx" Link="Model\Model1.edmx" />
<Compile Include="..\ClassLibrary1\Model1.Context.cs" Link="Model\Model1.Context.cs" />
<Compile Include="..\ClassLibrary1\Users.cs" Link="Model\User.cs" />
</ItemGroup>
設定完按重新建置後,應可以在方案總管中看到,物件模型已在Model資料夾中,並且檔案前面標示著捷徑箭頭圖案
若出現編譯錯誤
若出現以下編譯錯誤,請確定是否有用 NuGet 安裝 Entity Framework 套件
簡潔的參考撰寫方式
如果你有多個資料模型.cs
檔,不想一個一個寫參考,這裡找到一個方法用微軟後來加入的參數就可以解決這個問題。可以用*.cs
將所有.cs
檔,參考至LinkBase
所指定的資料夾路徑中
<Compile Include="..\ClassLibrary1\*.cs" LinkBase="Model" />
使用 Entity Framework 將資料庫指定資料表內容顯示在 DataGridView
先開啟 From1.cs檔 ,從左側的工具箱中,拖曳 DataGridView 物件到 Form1 畫面中,並在灰色區塊外的白色地方左鍵點擊兩下,會跳至程式碼區塊
接者撰寫以下程式碼,來使用 EF 連到資料庫,物件名稱為 Context.cs
中所生成的類別名稱,若跳出紅色底下,可以使用燈泡圖示來修正,引用我實際資料模型所在的 ClassLibrary1 命名空間
我們在Form1_Load()
這個方法中將資料庫中的 Users 資料表讀取後,餵到剛剛新增的 DataGridView 的資料來源中,寫完按 F5 執行測錯,應該可以看到錯誤畫面(哈哈
錯誤訊息是:System.InvalidOperationException: 'No connection string named 'TestDBEntities' could be found in the application config file.'
加入資料庫連線字串
因為使用ADO.NET 實體資料模型
時所建立的資料庫連線字串,儲存在我們的ClassLibary1
內的App.Config
檔案裡面,我們剛剛並沒有設定要參考到該檔案,我也不建議直接參考,因為裡面除了連線字串外,可能含有些我們 .NET 6 專案用不到的參數或設定。而資料庫連線字串其實會隨著你的部屬環境而變動,例如正式環境與測試環境用的是不同資料庫。所以這裡我們不直接參考ClassLibary1
裡面的App.Config
,而是對我們的 .NET 6 專案中,另外新增一個App.Config
檔案來儲存。(你也可以偷懶複製ClassLibary1
內的App.Config
檔案到 .NET 6 專案內,刪除不必要的設定,只保留連線字串)
下圖是ClassLibary1
內的App.Config
內容
.NET 6 專案內的App.Config
只包含連線字串的話應該如下,另外因為我們的 Model1 檔案室放在 Model 資料夾下,所以我其中的res
參數路徑需要額外加上 Model資料夾名稱(資料來源)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="TestDBEntities" connectionString="metadata=res://*/Model.Model1.csdl|res://*/Model.Model1.ssdl|res://*/Model.Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=DANNY-LIU-ASUS;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
補充:若出現System.Data.Entity.Core.MetadataException: 'Unable to load the specified metadata resource.'
這類錯誤訊息,請確認連線字串的參數或路徑是否有改錯
設定完後,按F5重新執行,在 DataGridView 中應可以正常顯示資料
大功告成,謝謝大家收看
延伸閱讀:
在.NET 5 / 6的 Windows Form 中使用 EF Core