使用 Entity Framework Core 時,通過代碼自動 Migration

來源:互聯網
上載者:User

標籤:

使用 Entity Framework Core 時,通過代碼自動 Migration一 介紹

  在使用 Entity Framework Core (下面就叫 EF Core 吧)進行開發時,如果模型有變動,我們要在用 EF Core 提供的命令列工具進行手工遷移,然後再運行程式。但是為了效率,我想能不能在程式的入口處進行 Migration 呢?從個人經驗來說應該是可以,因為 EF Tool 雖然提供了 CLI 但是它最終也是被程式解析這些命令。下面就開始分析,如何通過代碼進行 Migration 。

二 分析

  首先我們要先瞭解,在使用 EF Core 的 CLI 時,要執行兩個步驟:

    第一步:產生 Migration 檔案;

    第二步:更新變更項到資料庫;

  既然是先產生 Migration 檔案再更新,那麼在 EF Core 裡面一定有對應的模組做這件事情。下面我們看一下 EF Core 項目的結構。從中我們確實找到關於 Migration 的模組。在 Migrations/Design 目錄的類名稱上我們可以看出來,它就是產生 Migration 檔案的。這裡先到這兒。

  

  找到了產生 Migration 檔案的入口,我們再來找一下如何通過代碼將這些變更更新到資料庫中。

  在使用 EF Core 的時候,我們都要通過繼承 DbContext 來編寫自己的 DbContext 子類。在 DbContext 類中我們找到了一個 Database 屬性。如所示:

  

  然後查看了 DatabaseFacde 這個類,並沒有發現執行遷移相關的函數。通過程式碼搜尋,我在 RelationalDatabaseFacadeExtensions 這個類中有一個 Migration() 擴充方法。通過注釋的解析,我也確定了它就是執行 Migration 檔案,並將變更更新到資料庫。

  這兩個步驟對應的代碼我們都找到了,下面我們就編寫一段兒代碼,完成自動將模型變更更新到資料庫的功能。

 1 public class AutoMigration 2 { 3     private readonly IServiceProvider _serviceProvider; 4     private InformationDbContext _context; 5  6     public AutoMigration(IServiceProvider serviceProvider) 7     { 8         _serviceProvider = serviceProvider; 9         _context = serviceProvider.GetService<InformationDbContext>();10     }11 12     public void Migrator()13     {14         var path = Path.Combine(AppContext.BaseDirectory, "..\\..\\..\\Migrations\\");15         if (!Directory.Exists(path))16         {17             Directory.CreateDirectory(path);18         }19         else20         {21             Directory.GetFiles(path).ToList().ForEach(File.Delete);22         }23 24         using (_context)25         {26             var services = ((IInfrastructure<IServiceProvider>) _context).Instance;27             var codeHelper = new CSharpHelper();28             var scaffolder = ActivatorUtilities.CreateInstance<MigrationsScaffolder>(services,29                 new CSharpMigrationsGenerator(codeHelper, new CSharpMigrationOperationGenerator(codeHelper),30                     new CSharpSnapshotGenerator(codeHelper)));31             32             var projectDir = Path.Combine(path, "..\\");33             var migrationAssembly = new MigrationsAssembly(new CurrentDbContext(_context), _context.Options, new MigrationsIdGenerator());34             scaffolder.GetType().GetField("_migrationsAssembly", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(scaffolder, migrationAssembly);35 36             var readonlyDic = new ReadOnlyDictionary<string,TypeInfo>(new Dictionary<string, TypeInfo>());37             migrationAssembly.GetType().GetField("_migrations", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(migrationAssembly, new LazyRef<IReadOnlyDictionary<string, TypeInfo>>(readonlyDic));38             var migration = scaffolder.ScaffoldMigration("Information.Migrations", "Information");39 40             scaffolder.Save(projectDir, migration, path);41 42             //另外一種儲存方式43             //File.WriteAllText($"Migrations\\{migration.MigrationId}{migration.FileExtension}", migration.MigrationCode);44             //File.WriteAllText("Migrations\\" +45             //    migration.MigrationId + ".Designer" + migration.FileExtension,46             //    migration.MetadataCode);47             //File.WriteAllText("Migrations\\" + migration.SnapshotName + migration.FileExtension,48             //    migration.SnapshotCode);49         }50 51         using(_context = (InformationDbContext)_serviceProvider.GetService<IDbContext>())52         {53             _context.Database.Migrate();54         }55     }56 }

  另外一個注意點:我們需要指定一下遷移檔案所在項目。

1 services.AddDbContext<InformationDbContext>(opt =>2 {3     var connectionString = configuration["ConnectionStrings:DefaultConnection"];4     opt.UseSqlServer(connectionString, optionBuilder =>5     {6         optionBuilder.MigrationsAssembly("Information");7     });8 });

 

三 總結

  通過上面的分析可以知道,其實我們就是把 CLI 的兩個命令通過代碼實現了一下。在 Startup 檔案中進行調用即可。為什麼想這麼幹?因為在實際開發的時候,來回切換視窗心裡覺得不爽了唄。:)

使用 Entity Framework Core 時,通過代碼自動 Migration

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.