在生產(chǎn)環(huán)境下處理EFCore數(shù)據(jù)庫遷移的五種方法
在生產(chǎn)環(huán)境下處理EFCore數(shù)據(jù)庫遷移的五種方法
原文鏈接:https://www.thereformedprogrammer.net/handling-entity-framework-core-database-migrations-in-production-part-1/
作者:Jon P Smith,是《?Entity Framework Core in Action》的作者
安德魯·洛克(Andrew Lock)撰寫了精彩的系列文章《在ASP.NET Core中的應(yīng)用程序啟動(dòng)時(shí)運(yùn)行異步任務(wù)》,其中他以“遷移數(shù)據(jù)庫”為例,介紹了您可以在啟動(dòng)時(shí)執(zhí)行的操作。
在他該系列的第3部分中,他介紹了為什么在啟動(dòng)時(shí)遷移數(shù)據(jù)庫并不總是最佳選擇。我決定編寫一系列有關(guān)可以安全遷移數(shù)據(jù)庫的不同方法的系列文章,即使用Entity Framework Core(EF Core)更改數(shù)據(jù)庫的架構(gòu)。
這是本系列的第一部分,介紹如何創(chuàng)建遷移,而第二部分則介紹如何將遷移應(yīng)用于數(shù)據(jù)庫,特別是生產(chǎn)數(shù)據(jù)庫。在撰寫本文時(shí),我使用了與安德魯類似的方法,即,我嘗試使用EF Core的優(yōu)點(diǎn)和缺點(diǎn),一路介紹創(chuàng)建遷移腳本的所有方式。
注意:Andrew和我彼此認(rèn)識(shí),因?yàn)槲覀兺瑫r(shí)在為Manning Publications撰寫書籍:Andrew的書是“ ASP.NET Core in Action,而我寫的書是“ Entity Framework Core in Action ”。我們分享了當(dāng)作家的辛勞和喜悅,但是安德魯在ASP.NET Core方面的工作更加艱辛–他的書長700頁,而我的書“只有” 500頁。
TL; DR –創(chuàng)建遷移的摘要
注意:單擊鏈接可直接轉(zhuǎn)到涵蓋該點(diǎn)的部分。
?可以將兩種類型的遷移應(yīng)用于數(shù)據(jù)庫:?添加新的表,列等,稱為不間斷的更改(簡單)。?更改列/表并需要復(fù)制數(shù)據(jù),稱為重大更改(困難)。?有五種方法可以在EF Core中創(chuàng)建遷移?使用EF Core創(chuàng)建遷移-簡單,但不能處理所有可能的遷移。?使用EF Core創(chuàng)建遷移,然后手動(dòng)修改遷移-中到難,但處理所有可能的遷移。?使用第三方遷移構(gòu)建器來編寫C#遷移-很難,因?yàn)槟枰约壕帉戇w移,但是您不需要了解SQL。?使用SQL數(shù)據(jù)庫比較工具比較數(shù)據(jù)庫并輸出SQL更改腳本–很簡單,但是您確實(shí)需要對(duì)SQL有一定的了解。?通過復(fù)制EF Core的SQL來編寫自己的SQL遷移腳本 –很難理解,可以很好地控制,但您確實(shí)需要了解SQL。?如何確保您的遷移有效–使用CompareEfSql工具。
場(chǎng)景–關(guān)于創(chuàng)建遷移,我們應(yīng)該問什么問題?
有很多遷移數(shù)據(jù)庫模式的方法,在開發(fā)中,幾乎可以使用任何方法。但是,當(dāng)涉及到遷移生產(chǎn)數(shù)據(jù)庫(即實(shí)際用戶正在使用的數(shù)據(jù)庫)時(shí),它就變得非常嚴(yán)重。弄錯(cuò)了,至少會(huì)給您的用戶帶來不便,并且更糟的是,甚至?xí)G失您數(shù)據(jù)庫中的(寶貴)數(shù)據(jù)!
在獲得更新數(shù)據(jù)庫模式部分之前,我們需要構(gòu)建遷移腳本,該腳本將包含模式以及可能的數(shù)據(jù)更改。要構(gòu)建適當(dāng)?shù)倪w移腳本,我們需要問自己一些有關(guān)需要應(yīng)用到數(shù)據(jù)庫的更改類型的重要問題。所需的遷移將是:
1.一個(gè)非重大更改,也就是說,它只是增加了新的欄目,表格等,這可能而舊的軟件仍然運(yùn)行應(yīng)用,即舊的軟件將與遷移后的數(shù)據(jù)庫一起運(yùn)行。2.一個(gè)重大更改,即有些數(shù)據(jù)必須復(fù)制或遷移過程中轉(zhuǎn)化,無法應(yīng)用,而舊的軟件,即舊的軟件會(huì)遇到與遷移后的數(shù)據(jù)庫錯(cuò)誤(中斷服務(wù))。
本文中也介紹了我們正在使用EF Core,它帶來的一些好處和限制。好處是,在大多數(shù)情況下,EF Core可以自動(dòng)創(chuàng)建所需的遷移。
約束條件是應(yīng)用遷移后的數(shù)據(jù)庫必須與EF Core通過查看您的DbContext和映射的類建立的數(shù)據(jù)庫軟件模型匹配–我指的是帶有大寫M的EF Core模型,因?yàn)榇嬖谝粋€(gè)名為DbContext中的模型,其中包含類和數(shù)據(jù)庫之間的完整映射。
注意:我將介紹遷移,在這些遷移中,您可以控制映射到數(shù)據(jù)庫的類的控制和EF Core配置-有時(shí)也稱為代碼優(yōu)先方法。
我不會(huì)介紹另一種替代方法是,您直接控制數(shù)據(jù)庫,并使用稱為 scaffolding的EF Core命令為您創(chuàng)建實(shí)體類和EF Core配置。采用這種方法遷移很簡單–只需重新搭建數(shù)據(jù)庫即可。
第1部分,創(chuàng)建遷移腳本的五種方法
正如我在上一節(jié)中所述,我們創(chuàng)建的任何遷移腳本都必須將數(shù)據(jù)庫遷移到與EF Core Model匹配的狀態(tài)。例如,如果遷移在表中添加了新列,則映射到該表的實(shí)體類必須具有與該新列匹配的屬性。如果數(shù)據(jù)庫架構(gòu)的EF Core的模型確實(shí)與數(shù)據(jù)庫匹配,則您可能會(huì)在查詢或?qū)懭胫邪l(fā)生錯(cuò)誤。如果遷移腳本與該數(shù)據(jù)庫的EF Core模型匹配,則將其稱為創(chuàng)建“可用”數(shù)據(jù)庫。
毫無疑問,EF Core創(chuàng)建的遷移的有效性– EF Core創(chuàng)建了它,因此它將是有效的。但是,如果我們需要編輯遷移,或者我們自己進(jìn)行遷移構(gòu)建,那么我們需要非常小心,就EF Core而言,遷移會(huì)創(chuàng)建一個(gè)“可用”數(shù)據(jù)庫。這是我考慮過很多的事情。
這是創(chuàng)建遷移腳本的方法的列表。
?創(chuàng)建C#遷移腳本1.標(biāo)準(zhǔn)EF Core遷移腳本:使用EF Core的Add-Migration命令創(chuàng)建C#遷移腳本。2.手動(dòng)修改的EF Core遷移腳本:使用EF Core的Add-Migration命令創(chuàng)建C#遷移腳本,然后對(duì)其進(jìn)行手動(dòng)編輯以添加EF Core遺漏的位。3.使用第三方遷移構(gòu)建器,例如FluentMigrator。這樣的工具使您可以用C#編寫自己的遷移腳本。?創(chuàng)建SQL遷移腳本。1.使用SQL數(shù)據(jù)庫比較工具。它將最后一個(gè)數(shù)據(jù)庫架構(gòu)與EF Core創(chuàng)建的新數(shù)據(jù)庫架構(gòu)進(jìn)行比較,并生成一個(gè)SQL腳本,該腳本會(huì)將舊數(shù)據(jù)庫遷移到新數(shù)據(jù)庫架構(gòu)。2.編寫自己的SQL遷移腳本。稱職的SQL編寫者可以通過捕獲SQL EF Core用來創(chuàng)建數(shù)據(jù)庫的方式來編寫SQL遷移腳本。
這是一個(gè)摘要圖,可讓您對(duì)這五種方法進(jìn)行總體回顧,并就其易用性和局限性提出個(gè)人看法。

[1]
現(xiàn)在,讓我們依次看一看。
1a,標(biāo)準(zhǔn)EF Core C#遷移腳本
這是EF Core提供的標(biāo)準(zhǔn)遷移技術(shù)。Microsoft官方文檔中提供了充分的文檔記錄[2],總而言之,您運(yùn)行了一個(gè)名為Add-Migration的命令,該命令將三個(gè)C#文件添加到您的應(yīng)用程序,其中包含使用Add-Migration 遷移現(xiàn)有數(shù)據(jù)庫以匹配當(dāng)前EF Core設(shè)置/配置所需的更改。
| 好處 | ·自動(dòng)構(gòu)建遷移 ·無需學(xué)習(xí)SQL ·包括還原遷移功能 |
| 壞處 | |
| 局限性 | 標(biāo)準(zhǔn)遷移無法處理重大更改(但請(qǐng)參見1b)。不處理SQL功能,例如SQL用戶定義的函數(shù)(但請(qǐng)參見1b)。 |
| 提示 | 運(yùn)行“添加遷移”方法時(shí)請(qǐng)注意錯(cuò)誤消息。如果EF Core檢測(cè)到可能丟失數(shù)據(jù)的更改,它將輸出一條錯(cuò)誤消息,但仍會(huì)創(chuàng)建遷移文件。您必須更改遷移腳本,否則將丟失數(shù)據(jù)–請(qǐng)參閱第1b節(jié)。·如果您的DbContext在另一個(gè)注冊(cè)了DbContext的程序集中,則需要在構(gòu)建中使用MigrationsAssembly方法,并且很可能需要在DbContext程序集中實(shí)現(xiàn)IDesignTimeDbContextFactory。 |
| 結(jié)論 | 這是處理遷移的一種非常簡單的方法,并且在許多情況下效果很好。問題是,如果遷移無法滿足您的需求,將會(huì)發(fā)生什么情況。幸運(yùn)的是,有很多方法可以解決這個(gè)問題。 |
參考:Microsoft的有關(guān)創(chuàng)建遷移的文檔[3]。
1b,手工修改的EF Core C#遷移腳本
關(guān)于EF Core的Add-Migration命令的好處是,它以C#遷移文件為起點(diǎn),但是您可以自己編輯這些文件以添加代碼來處理重大更改或添加/更新數(shù)據(jù)庫的SQL部分。Microsoft提供了通過復(fù)制數(shù)據(jù)處理重大更改的示例。
| 好處 | 與標(biāo)準(zhǔn)遷移相同+ ·能夠自定義遷移?!つ軌虬琒QL功能,例如SQL用戶定義的功能。 |
| 壞處 | ·您需要了解數(shù)據(jù)庫中正在隱藏的內(nèi)容?!た赡茈y以決定如何編輯文件,例如,您是否保留了EF Core的所有內(nèi)容,然后對(duì)其進(jìn)行了更改,還是刪除了EF Core部件并自己完成了? |
| 局限性 | 沒有簡單的方法來檢查遷移是否正確(但請(qǐng)參閱稍后的CompareEfSql)。 |
| 提示 | 與標(biāo)準(zhǔn)遷移相同。 |
| 結(jié)論 | 非常適合進(jìn)行較小的更改,但由于經(jīng)常將C#命令與SQL混合使用,因此進(jìn)行較大的更改可能很困難。這就是為什么我不使用EF Core遷移的原因之一。 |
參考:Microsoft手動(dòng)修改遷移的示例[4]。
1c.使用第三方C#遷移構(gòu)建器
安德魯·洛克(Andrew Lock)向我指出了一種使用FluentMigrator編寫遷移的方法。這與EF遷移的工作原理類似,但是您必須完成詳細(xì)說明更改的所有艱苦工作。好消息是FluentMigrator的命令非常明顯。
| 好處 | 不需要學(xué)習(xí)SQL。能明顯的看到更改了什么,即“代碼作為文檔”。 |
| 壞處 | ·您必須確定自己所做的更改。不保證產(chǎn)生“正確的”遷移(但請(qǐng)參閱稍后的CompareEfSql)。 |
| 局限性 | - 沒有 - |
| 提示 | 請(qǐng)注意,F(xiàn)luentMigrator有一個(gè)“ Migration Runners”,可以將更新應(yīng)用于數(shù)據(jù)庫,但也可以輸出SQL腳本。 |
| 結(jié)論 | 我自己沒有真正的經(jīng)驗(yàn)。感覺這是EF Core遷移的一種更清晰的語法,但是您必須自己完成所有工作。 |
參考:GitHub的FluentMigrator[5]。
2a.使用SQL數(shù)據(jù)庫比較工具

有免費(fèi)的和商業(yè)的工具可以比較兩個(gè)數(shù)據(jù)庫并創(chuàng)建一個(gè)SQL更改腳本,該腳本將舊數(shù)據(jù)庫架構(gòu)遷移到新數(shù)據(jù)庫架構(gòu)。
Visual Studio 2017(所有版本)中的“視圖”選項(xiàng)卡下內(nèi)置了一個(gè)名為“SQL Server Object Explorer”的“免費(fèi)”比較工具。如果右鍵單擊數(shù)據(jù)庫,則可以訪問“比較模式”工具(請(qǐng)參見右圖),該工具可以生成SQL更改腳本。
SQL Server的對(duì)象資源管理器工具是非常好的,但是沒有(可惜)多文檔。其他商業(yè)系統(tǒng)包括Redgate的SQL Compare。
| 好處 | 為您構(gòu)建正確的SQL遷移腳本。 |
| 壞處 | ·您需要對(duì)數(shù)據(jù)庫有一點(diǎn)了解?!げ⒎撬械腟QL比較工具都生成還原腳本。 |
| 局限性 | 不處理重大更改-需要人工輸入。 |
| 提示 | 請(qǐng)注意SQL比較工具,該工具可以輸出日光下的所有設(shè)置,以確保設(shè)置正確。EF Core的遷移非常簡單,例如“ CREATE TABLE…”,因此應(yīng)該這樣做。如果您有任何特定設(shè)置,則將它們構(gòu)建到數(shù)據(jù)庫create中。 |
| 結(jié)論 | 我在難以手動(dòng)編碼的大型遷移中使用了SQL Server對(duì)象資源管理器。對(duì)不熟悉SQL語言的人非常有用,尤其有用。 |
2b.手工編碼SQL遷移腳本
這聽起來確實(shí)很困難-編寫自己的SQL遷移,但是手頭上有很多幫助,無論是來自SQL比較工具(參見上文),還是查看SQL EF Core用于創(chuàng)建數(shù)據(jù)庫的幫助。這意味著我可以查看并復(fù)制以構(gòu)建結(jié)論SQL遷移腳本的SQL。
| 好處 | 完全控制數(shù)據(jù)庫結(jié)構(gòu),包括EF Core不會(huì)添加的部分,例如用戶定義的函數(shù),列約束等。 |
| 壞處 | ·您必須了解基本的SQL,如CREATE TABLE等?!つ仨毚_定自己所做的更改(但有幫助) ·不能進(jìn)行自動(dòng)還原遷移?!げ槐WC產(chǎn)生“正確的”遷移(但請(qǐng)參閱稍后的CompareEfSql)。 |
| 局限性 | - 沒有 - |
| 提示 | ·我使用一個(gè)單元測(cè)試來捕獲EF Core的確保創(chuàng)建方法的日志輸出。那讓我得到了實(shí)際的SQL EF Core輸出。然后,我尋找最后一個(gè)數(shù)據(jù)庫的差異。這使得編寫SQL遷移更加容易。? ?·通過應(yīng)用所有遷移(包括新遷移)創(chuàng)建數(shù)據(jù)庫,然后運(yùn)行CompareEfSql來檢查數(shù)據(jù)庫是否與EF Core的當(dāng)前數(shù)據(jù)庫模型匹配,從而對(duì)遷移進(jìn)行單元測(cè)試。 |
| 結(jié)論 | 這是我使用的,在CompareEfSql工具的幫助下。如果EF Core的遷移功能非常好,為什么還要處理所有這些麻煩呢?這是結(jié)論原因:·完全控制數(shù)據(jù)庫結(jié)構(gòu),包括EF Core不會(huì)添加的部分,例如用戶定義的函數(shù),列約束等?!び捎谖艺诰帉慡QL,因此使我考慮了數(shù)據(jù)庫的各個(gè)方面。更改–該屬性是否可以為空?我需要索引嗎?等 ·通過手動(dòng)修改EF Core的遷移系統(tǒng)來應(yīng)對(duì)重大變化并非易事。我還是堅(jiān)持使用SQL遷移。這是針對(duì)想要完全控制和可視化遷移的開發(fā)人員的。 |
您可以捕獲EF Core的SQL輸出以創(chuàng)建數(shù)據(jù)庫,但是可以在調(diào)用方法 EnsureCreated ( EnsureCreated 方法用于創(chuàng)建單元測(cè)試數(shù)據(jù)庫)時(shí)捕獲EF Core的日志記錄。因?yàn)闉镋F Core設(shè)置日志記錄有些復(fù)雜,所以我在EfCore.TestSupport庫中添加了輔助方法來處理該問題。這是一個(gè)示例單元測(cè)試,它創(chuàng)建一個(gè)新的SQL數(shù)據(jù)庫并捕獲EF Core生成的SQL命令。
[RunnableInDebugOnly]publicvoidCaptureSqlEfCoreCreatesDatabaseToConsole(){//SETUPvar options = this.CreateUniqueClassOptionsWithLogging<BookContext>(log => _output.WriteLine(log.Message));using(var context = newBookContext(options)){//ATTEMPTcontext.Database.EnsureDeleted();context.Database.EnsureCreated();}}
讓我們看一下這段代碼的每一行
?第5行。這是一個(gè)EfCore.TestSupport方法,為您的DbContext創(chuàng)建選項(xiàng)。此版本使用包含類名的數(shù)據(jù)庫名稱。我這樣做是因?yàn)閤Unit測(cè)試類是并行運(yùn)行的,所以我想要此單元測(cè)試類的唯一數(shù)據(jù)庫。?第6行。我使用以... WithLogging結(jié)尾的選項(xiàng)生成器的版本,該版本允許我捕獲日志輸出。在這種情況下,我將日志的Message部分直接輸出到單元測(cè)試輸出窗口。?第11和12行。首先,我確保刪除數(shù)據(jù)庫,以便在我調(diào)用確保創(chuàng)建時(shí),將使用由當(dāng)前DbContext的配置和映射的類定義的架構(gòu)來創(chuàng)建一個(gè)新的數(shù)據(jù)庫。
以下是在單元測(cè)試輸出中捕獲的部分輸出。這為您提供了EF Core用于創(chuàng)建整個(gè)架構(gòu)的確切SQL。您確實(shí)只需要提取與遷移有關(guān)的部分,但是至少您可以將所需的部分剪切并粘貼到SQL遷移腳本中。
CREATE DATABASE [EfCore.TestSupport-Test_TestEfLogging];ExecutedDbCommand(52ms) [Parameters=[], CommandType='Text', CommandTimeout='60']IF SERVERPROPERTY('EngineEdition') <> 5BEGINALTER DATABASE [EfCore.TestSupport-Test_TestEfLogging] SET READ_COMMITTED_SNAPSHOT ON;END;ExecutedDbCommand(5ms) [Parameters=[], CommandType='Text', CommandTimeout='30']CREATE TABLE [Authors] ([AuthorId] int NOT NULL IDENTITY,[Name] nvarchar(100) NOT NULL,CONSTRAINT [PK_Authors] PRIMARY KEY ([AuthorId]));ExecutedDbCommand(1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']CREATE TABLE [Books] ([BookId] int NOT NULL IDENTITY,[Title] nvarchar(256) NOT NULL,-- rest of SQL left out
如何確保您的遷移有效–使用CompareEfSql工具
在創(chuàng)建遷移的描述中,我曾多次提到CompareEfSql。該工具將數(shù)據(jù)庫與EF Core首次用于DbContext時(shí)創(chuàng)建的數(shù)據(jù)庫模型進(jìn)行比較。通過DbContext實(shí)例中的Model屬性訪問此模型,是通過查看DbContext配置以及DbSet和DbQuery屬性來構(gòu)建結(jié)論EF Core的。
這使開發(fā)人員可以根據(jù)EF Core Model測(cè)試現(xiàn)有數(shù)據(jù)庫,并在錯(cuò)誤消息不同的情況下為您提供錯(cuò)誤消息。我發(fā)現(xiàn)這是一個(gè)非常強(qiáng)大的工具,它使我可以手動(dòng)編碼SQL遷移,并確保它們是正確的有一些小限制。這是一個(gè)示例單元測(cè)試,如果數(shù)據(jù)庫架構(gòu)與EF Core的模型不匹配,該測(cè)試將失敗。
[Fact]publicvoidCompareViaContext(){//SETUPvar options = … options that point to the database to check;using(var context = newBookContext(options)){var comparer = newCompareEfSql();//ATTEMPT//This will compare EF Core model of the database//with the database that the context's connection points tovar hasErrors = comparer.CompareEfWithDb(context);//VERIFY//The CompareEfWithDb method returns true if there were errors.//The comparer.GetAllErrors property returns a string//where each error is on a separate linehasErrors.ShouldBeFalse(comparer.GetAllErrors);}}
我喜歡這個(gè)工具,它位于EFCore.TestSupport開源庫中。它使我能夠構(gòu)建遷移,并確保它們能夠正常工作。我也將其作為正常的單元測(cè)試來運(yùn)行,它會(huì)立即告訴我是否是我或另一個(gè)同事更改了EF Core的設(shè)置。
您可以在名為EF Core的文章中獲得對(duì)該工具的更詳細(xì)的描述:完全控制數(shù)據(jù)庫模式及其許多功能和配置可以在CompareEfSql文檔頁面中找到[7]。
注意:我最初是為EF6.x構(gòu)建此版本的(請(qǐng)參閱此舊文章),但是由于EF6.x并未完全公開其內(nèi)部模型而受到限制。
有了EF Core,我可以做更多的事情,現(xiàn)在我可以檢查幾乎所有內(nèi)容,并且因?yàn)槲依昧薊F Core的腳手架服務(wù),所以它適用于EF Core支持的任何數(shù)據(jù)庫。
結(jié)論–第1部分
本系列的這一部分將介紹如何創(chuàng)建有效的遷移,而第二部分則涉及將遷移應(yīng)用于數(shù)據(jù)庫。本文列出了使用EF Core時(shí)用于創(chuàng)建數(shù)據(jù)庫遷移的所有適用方法-優(yōu)缺點(diǎn)。如您所見,EF Core的Add-Migration命令確實(shí)很好,但是并不能涵蓋所有情況。
由您決定要遇到的遷移類型,以及您希望對(duì)數(shù)據(jù)庫架構(gòu)進(jìn)行何種級(jí)別的控制。如果您僅使用EF Core的標(biāo)準(zhǔn)遷移(1a)就可以擺脫困境,那么這將使您的生活更輕松。但是,如果您預(yù)期會(huì)發(fā)生重大變化,或者需要設(shè)置額外的SQL功能,那么您現(xiàn)在知道可用的選項(xiàng)。
令人擔(dān)心的部分出現(xiàn)在part2中-將遷移應(yīng)用于生產(chǎn)數(shù)據(jù)庫。更改包含關(guān)鍵業(yè)務(wù)數(shù)據(jù)需求(需求?。┑臄?shù)據(jù)庫,請(qǐng)仔細(xì)計(jì)劃和測(cè)試。您需要考慮如果(何時(shí)!)遷移因錯(cuò)誤而失敗時(shí)該怎么辦。
我放棄EF6中的EF遷移的最初原因是它在啟動(dòng)時(shí)自動(dòng)遷移運(yùn)行良好,但它在部署時(shí)引發(fā)錯(cuò)誤!而且很難找到遷移中的錯(cuò)誤-僅此一項(xiàng)就使我遠(yuǎn)離使用EF遷移(要獲得更多信息,可以查看這篇老文章[8])。
EF Core的遷移處理要比EF6更好:已可以實(shí)現(xiàn)自動(dòng)遷移,并且EF Core遷移對(duì)git-merge更加友好,僅提及兩個(gè)更改。
而且,我構(gòu)建SQL遷移腳本的方式使我比正在運(yùn)行Add-Migration時(shí)要更加仔細(xì)地思考自己在做什么。EF Core是一個(gè)非常出色的O / RM,有時(shí)確實(shí)有許多隱藏功能。創(chuàng)建SQL遷移腳本使我從數(shù)據(jù)庫的角度考慮了遷移問題,而且我經(jīng)常會(huì)對(duì)數(shù)據(jù)庫和C#代碼的一些細(xì)微調(diào)整,以使數(shù)據(jù)庫更好的運(yùn)行。
References
[1]?充分的文檔記錄:?https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/
[2]?Microsoft的有關(guān)創(chuàng)建遷移的文檔:?https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/#create-a-migration[3]?Microsoft手動(dòng)修改遷移的示例:?https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/#customize-migration-code[4]?GitHub的FluentMigrator:?https://github.com/fluentmigrator/fluentmigrator[5]:https://www.thereformedprogrammer.net/wp-content/uploads/2019/01/SQLServerObjectExplorerCompareSchema.png
[6]?CompareEfSql文檔頁面中找到:?https://github.com/JonPSmith/EfCore.TestSupport/wiki/9.-EfSchemaCompare[7]?老文章:?https://www.thereformedprogrammer.net/handling-entity-framework-database-migrations-in-production-part-1-applying-the-updates/
