[ASP.net Core] 使用Entity Framework Core Database First方式 ...
文章推薦指數: 80 %
access data through Entity Framework Core Database First in separate classlibrary project. 嚴格來說,標題應該取名Code First from Database.
accessdatathrough EntityFrameworkCore DatabaseFirstinseparateclasslibraryproject嚴格來說,標題應該取名CodeFirstfromDatabase.Netframework時期就有類似的玩意兒↓
前言趁著.netCore2剛推出,把最近從恆逸資訊上課的記憶抄寫下來,畢竟發現.netCore好多事情要自己手動處理以前.NetFramework要透過EntityFramework存取資料,大概步驟如下:1.專案先透過NuGet加入EntityFramework套件參考2.專案加入*.edmx(EFDesignerfromDatabaseFirst開發方式)3.把自己的XXXContext物件(有繼承DbContext類別的那個)new出來即可存取資料。
以上對話框點一點選一選就完成了XD然而在.netCore變成....1.專案先透過NuGet加入Microsoft.EntityFrameworkCore.SqlServer套件參考(此為專門存取SqlServer用的Provider)還有Microsoft.EntityFrameworkCore.Tools(此為從資料庫建立模型Class的用途)如果是ASP.netCore2的專案,上述兩個預設都已經加好在Microsoft.AspNetCore.All套件底下如果是一般ClassLibrary專案則要自己手動加入那兩個套件。
2..NetCore沒有*.edmx檔,取而代之必須下指令產生一堆*.cs模型3.各種地方相依性注入(連線字串、XXXDbContext....等等)4.由於已透過相依性注入取得物件,所以不必每次存取資料前都把XXXContextnew出來,這一點倒是在Controller減少了些程式碼實作本文環境:Win10、VisualStudio201715.5.5、SQLServer2014DeveloperEdition以下StepbyStep,照著做應該就可以建立出ASP.netCore2網站透過另一個類別庫專案的EntityFrameworkCore2來存取資料。
※ASP.netCore3、.Net5之後的專案大同小異,只差別在Startup.cs基本程式碼不一樣,未來就不累述了1.建立一個ASP.netCore2乾淨的空白Web專案上述的Web應用程式範本為.netCore2新推出的RazorPage架構,很像以前的asp,只是多了PageModel可以資料繫結而它右邊的Web應用程式(模型-檢視-控制器)範本才是熟悉的MVC架構,這裡選「空白」,別讓VisualStudio多加其他有的沒的程式碼混淆視聽XD 2.對著方案右鍵,加入新增.NETStandard類別庫專案(如此建置出來的類別庫才能供.netCore和.netframework兩邊使用)※如果你很確定會用到這個DBAccess的專案都是.NetCore的話,類別庫專案也是可以選擇.NetCore而非.NetStandard此類別庫專案就是專門存放資料模型的專案※.Net5的話,目標Framework就一律選.Net5吧預設多出來的Class1.cs檔案可以刪除,然後對著ClassLibrary類別庫專案右鍵>管理NuGet套件依序加入「Microsoft.EntityFrameworkCore.SqlServer」、「Microsoft.EntityFrameworkCore.Tools」這兩個套件Microsoft.EntityFrameworkCore.Tools和Microsoft.EntityFrameworkCore.Tools.DotNet兩者都可以把DB轉成Class模型只是差在後續Console指令下得不一樣既然微軟官方寫Microsoft.EntityFrameworkCore.Tools那就裝Microsoft.EntityFrameworkCore.Tools就好了微軟官網:在ASP.NETCore上使用EFCore搭配現有資料庫的使用者入門※2019-03-19追記:透過Nuget加入兩個套件「Microsoft.EntityFrameworkCore.SqlServer」、「Microsoft.EntityFrameworkCore.Tools」記得版本都選擇相同↓版本不同的話,應該會發生如下錯誤↓ 3.確認資料庫的資料準備好了4.VisualStudo最上方的選單工具>開啟套件管理器主控台,準備下指令在主控台Consoel要下的指令↓Scaffold-DbContext"Server=.\sqlexpress2014;Database=Blogging;Trusted_Connection=True;"Microsoft.EntityFrameworkCore.SqlServer-OutputDirModels-Force-UseDatabaseNames-TablesBlog,PostScaffold-DbContext為剛剛安裝Tools套件的指令,DB連線字串依自己情況決定-OutputDir指定要輸出到專案根目錄下哪個資料夾,本文為Models資料夾-Force為工具產出的.cs檔要強制覆寫現存檔案(DB欄位Schema異動後,就給這個)-Tables參數,指定只需要載入哪些資料表(以逗號區隔),留意大小寫最好和DB裡一樣避免出現黃字警告,沒給-Tables參數的話,預設抓DB全部的Table-UseDatabaseNames,程式碼產生出來的類別名稱要和資料庫裡的一模一樣其它參數請見官網說明:EntityFrameworkCore工具的參考-VisualStudio中的套件管理員主控台以下是執行完指令後的結果↑上面得留意主控台的預設專案要選對專案,這會影響Model(.cs檔)輸出到哪個專案※2019-03-19追記:整個程式碼路徑不可以有中文或特殊符號,否則會報錯錯誤訊息可能是 「Unabletoresolvestartupproject''.Usingproject'DBClassLibrary'asthestartupproject.Thespecifiedframeworkversion'2.1'couldnotbeparsedThespecifiedframework'Microsoft.NETCore.App',version'2.1'wasnotfound. -Checkapplicationdependenciesandtargetaframeworkversioninstalledat: C:\ProgramFiles\dotnet\ -Installing.NETCoreprerequisitesmighthelpresolvethisproblem: https://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409 -The.NETCoreframeworkandSDKcanbeinstalledfrom: https://aka.ms/dotnet-download -Thefollowingversionsareinstalled: 2.1.9at[C:\ProgramFiles\dotnet\shared\Microsoft.NETCore.App]」或「Scaffold-DbContext:以"1"引數呼叫"GetFullPath"時發生例外狀況:"不合法的路徑格式。
"位於線路:1字元:1+Scaffold-DbContext"Server=.\sqlexpress2014;Database=MyDB;Trusted_Connect...+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +CategoryInfo :NotSpecified:(:)[Scaffold-DbContext],MethodInvocationException +FullyQualifiedErrorId:ArgumentException,Scaffold-DbContext」↓我專案路徑含有[ ]就這樣報錯.....※2021-04-09追記:貌似到了.Net5要把類別庫專案設定為啟動專案再輸入指令,Web專案才不會出現錯誤訊息無法參考「Microsoft.EntityFrameworkCore.Design」的樣子↓如果出現黃字請忽略它,程式還是可以正常執行,只是DB中原本不允許NULL的bool欄位變成C#的bool?型別(容我日後有空再想辦法處理)主控台指令完畢後,接著到XXXContext.cs裡,把OnConfiguring方法刪除,微軟建議改使用相依性注入方式設定DB連線字串完整程式碼如下:usingSystem;
usingMicrosoft.EntityFrameworkCore;
usingMicrosoft.EntityFrameworkCore.Metadata;
namespaceDBClassLibrary.Models
{
publicpartialclassBloggingContext:DbContext
{
publicvirtualDbSet
6.對著ASP.netCore專案右鍵新增>加入項目,選ASP.net組態檔(appsettings.json)要把本機開發時期的DB連線字串填進去,網站正式上線時,此檔案內容要記得修改↑因為是json格式,所以反斜線兩次跳脫字元7.DB連線字串配置好後,要在網站啟動時,讀取該連線字串,並註冊服務要使用資料庫XXXContext物件開啟Startup.cs檔,完整程式碼和說明如下:Asp.netCore2↓usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Threading.Tasks;
usingMicrosoft.AspNetCore.Builder;
usingMicrosoft.AspNetCore.Hosting;
usingMicrosoft.AspNetCore.Http;
usingMicrosoft.Extensions.DependencyInjection;
/*引用*/
usingMicrosoft.Extensions.Configuration;
usingMicrosoft.EntityFrameworkCore;
namespaceCoreWebSite
{
publicclassStartup
{
//使用相依性注入方式取得物件
privateIConfiguration_config;
publicStartup(IConfigurationconfig)
{
this._config=config;
}
//註冊服務
publicvoidConfigureServices(IServiceCollectionservices)
{
//↓待會在Controller便可使用相依性注入取得BloggingContext物件
services.AddDbContext");
foreach(DBClassLibrary.Models.Blogiteminquery)
{
sb.Append($@"
");
}
//懶得加View,所以用Content回傳,意思有到就好XD
returnContent(sb.ToString(),"text/html",Encoding.UTF8);
}
}
}執行結果完成↓※2019-05-06追記,在View(*.cshtml)注入DbContext方式@injectDBClassLibrary.Models.BloggingContextcontext
※2019-05-07追記,如何在ActionFilter中存取DbContextUseDbContextinActionFilterMiddleware ※2021-03-19追記,如果編譯無誤執行時期發生InvalidOperationException:Theentitytype'YourClassName'requiresaprimarykeytobedefined.Ifyouintendedtouseakeylessentitytypecall'HasNoKey()'.這種錯誤,應該是你的資料庫Table裡有取名兩個以上欄位叫XXXA_ID、XXXB_IDEntityFrameworkCore無法識別哪一個欄位是PrimaryKey,這種情況要到YourClass.cs把PKProperty加上[Key]就可以了↓usingSystem;
usingSystem.Collections.Generic;
//引用這個↓
usingSystem.ComponentModel.DataAnnotations;
namespaceWeb_Event.DBModels
{
publicpartialclassYourClass
{
//↓加這個
[Key]
publiclongsysid{get;set;}
publiclongUserCouponCode_SystemID{get;set;}
publicstringvouch_no{get;set;}
}
} 補充如果想更新資料庫模型檔案(*.cs)的話,就直接在套件管理器主控台再下同樣的Scaffold-DbContext指令(記得加上-force覆蓋原始檔案)即可。
若是手動誤刪Models資料夾把底下所有模型都刪除,而想再重新產生模型檔案,可能會出現錯誤訊息:Buildfailed.解決方法如下先把其它專案都卸載,然後類別庫專案設為起始專案再下指令會發生另一錯誤Startupproject'DBClassLibrary'targetsframework'.NETStandard'.Thereisnoruntimeassociatedwiththisframework,andprojectstargetingitcannotbeexecuteddirectly.TousetheEntityFrameworkCorePackageManagerConsoleToolswiththisproject,addanexecutableprojecttargeting.NETFrameworkor.NETCorethatreferencesthisproject,andsetitasthestartupproject;or,updatethisprojecttocross-target.NETFrameworkor.NETCore.大意是說,想使用EFCore的話,要有一個可直接執行的專案(例如:ASP.netCore)參考此類別庫專案並設為起始專案才行(但我們剛剛已試過會發生Buildfailed,所以此法行不通)或另一辦法,修改此專案為跨平台專案,如下:編輯類別庫專案的.csproj檔
延伸文章資訊
- 1Database First - EF6 | Microsoft Learn
- 2EF Core DB First測試- HackMD
tags: `DotNet Core` `Entity Framework` # EF Core DB First測試近期要寫簡單的Web API,在使用已包好的DB類別庫剛好沒.
- 3ASP.NET Core 3.0 如何使用Database First - ikevin 筆記本
ASP.NET Core 3.0 如何使用Database First ; Step 1. 先建立資料庫,這是參考文章提供的 ; Step 2. 從NuGet 安裝必要套件. Microsoft...
- 4EF Core Database-First Tutorial for .NET Core - Devart
- 5Entity Framework Core with Existing Database
Creating entity & context classes for an existing database is called Database-First approach. EF ...