如何將EFCore遷移分離到單獨類庫項目?


     上篇文章: EFCore生產環境數據庫升級方案 中我們聊了如何將EFCore遷移(實體模型變更)應用到生產環境的方案,在上次的演示中,我們是將所有遷移存放到了定義DbContext的類庫項目中去,在這邊文章中我來介紹下如何將遷移單獨存放到一個類庫項目中去,以便管理EF生成的遷移文件。

這篇文章中,我們繼續使用 EFCore生產環境數據庫升級方案 中的例子項目進行改造,來實現將所有EF遷移文件單獨提取到類庫項目中去,本文和 EFCore生產環境數據庫升級方案 是同一個系列的文章,如果你還沒有閱讀前一篇文章,強烈建議先閱讀前文。

一、新建類庫項目,將EF遷移文件及遷移快照文件移動到新的類庫項目中

新建名稱為 EFMigrations.DataMigrations 的類庫項目

這里需要注意的是:如果還沒有生成任何遷移文件,則請先至少生成一個,再將新生成的遷移文件復制到新建的類庫項目EFMigrations.DataMigrations 中去。

二、類庫項目添加對包含DbContext上下文類的引用。

添加EFMigrations.Models類庫項目的引用到EFMigrations.DataMigrations,如下:

 

三、將默認的遷移程序集指定為新建的類庫項目。

將EFMigrations.Models 中的所有的EF遷移文件及遷移生成的SQL腳本文件移動到EFMigrations.DataMigrations項目中去。

移動完畢后,EFMigrations.Models中僅包含EF DbContext 上下文類,以及實體模型,如下圖所示:

四、告訴啟動項目遷移程序集是哪個

啟動項目指的是告訴 EF命令行遷移工具從哪個項目開始啟動,然后執行遷移文件的生成,這里我們的啟動項目是EFMigrations.Web 項目,修改Startup.cs文件中的ConfigureService方法如下:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<MyDbContext>(builder=> {
                builder.UseSqlServer(Configuration["ConnectionStrings:ConnectionStr"],optionsBuilder=> {
                    //這里告訴EFcore 命令行遷移工具,等下生成的遷移文件放到EFMigrations.DataMigrations 項目中去。
                    optionsBuilder.MigrationsAssembly("EFMigrations.DataMigrations");
                });
            });
            services.AddControllersWithViews();
        }

添加EFMigrations.DataMigrations的引用到EFMigrations.Web,然后重新生成下EFMigrations.Web項目,否則等下生成遷移會失敗,因為不添加引用等下EFMigrations.Web項目啟動后開始生成遷移的時候會找不到EFMigrations.DataMigrations.dll

 

五、測試新添加的遷移是否正常生成到了新建的類庫項目中去。

我們新建一個實體模型OrderInfo,並將其添加到DbContext 上下文中去。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;

namespace EFMigrations.Models
{
    public class OrderInfo
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int OrderId { get; set; }
        public int ProductId { get; set; }
        public double Price { get; set; }
        public int BuyCount { get; set; }
        public int UserId { get; set; }
    }
}

 

修改DbContext上下文類,增加OrderInfo實體映射。

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;

namespace EFMigrations.Models
{
    public class MyDbContext : DbContext
    {
        /// <summary>
        /// 這里一定要聲明一個接收DbContextOptions參數的構造函數,否則無法正常添加遷移。
        /// </summary>
        /// <param name="options"></param>
        public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
        {
        }
        public DbSet<UserInfo> UserInfos { get; set; }
        public DbSet<OrderInfo> OrderInfos { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
        }
    }
}

 

打開程序包管理控制台,輸入以下命令:

cd ./EFMigrations.DataMigrations  將當前目錄定位到遷移程序所在項目的根目錄下,免得下面這個步驟生成遷移文件的時候還要額外用-p 參數指定遷移程序集的項目路徑。

dotnet ef migrations add OrderInfo_CreateTable -s ../EFMigrations.Web 

遷移生成成功后如下:

將新生成的遷移轉換成SQL,在程序包管理控制台中輸入以下命令:

dotnet ef migrations script 20210830142733_UserInfo_AddColumns 20210902141104_OrderInfo_CreateTable -s ../EFMigrations.Web -o ./SqlScripts/OrderInfo_CreateTable.sql

以上命令的意思是將 20210830142733_UserInfo_AddColumns遷移(不包含)的下一個遷移開始,截止到 20210902141104_OrderInfo_CreateTable(包含) 之間的所有遷移轉換成SQL腳本進行生成,生成成功后,SQL腳本如下:

 

六、將SQL腳本升級到數據庫

  • 首先需要將生成的SQL腳本設置成在生成項目的時候嵌入到程序集:鼠標右擊 OrderInfo_CreateTable.sql ,選擇屬性->生成操作->嵌入的資源
  • 然后將EFMigrations.Models 類中的 ApplicationBuilderExtensions 類移動到EFMigrations.DataMigrations項目中去,之所以這么做是方便dbup-sql 類庫找.sql腳本時直接從當前程序集中查找

       

  • 重啟網站,看下是否新SQL腳本是否成功被升級到了數據庫

這里需要注意的是,由於在上一篇文章中我已經將前面兩個SQL 腳本升級到了數據庫中,並且很有意思的事情是dbup-sqlserver記錄已升級腳本的名稱時帶上了程序集明明空間,因此這里直接運行會升級失敗,我們必須手動先將數據庫中的已升級腳本記錄的前綴名稱更新為EFMigartions.DataMigrations開頭方能再次升級成功。

我們將EFMigrations.Models替換成EFMigrations.DataMigrations后再重新升級,如下圖顯示,表示升級成功了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM