星期五, 1月 05, 2024

[EFCore] Migration

在該 [EFCore] 在 Console 專案上安裝設定 內筆記 Scaffold-DbContext 使用,該篇記錄 EF Core 8 使用 Code First Migration 操作

套件安裝

使用 EFCore 相關 nuget 套件,分別為
  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Tool
安裝 Microsoft.EntityFrameworkCore.Tool 才能使用 Migration 相關 API,另外 Microsoft.EntityFrameworkCore.Tool 安裝時就內含 Microsoft.EntityFrameworkCore.Design,不需要特別去安裝



建立 DbContext 和 Model 

資料型態有兩種指定方式分別為 Data Annotations 和 FluentAPI,實務上統一一種方式來進行指定就行,該筆記練習會同時使用

手動建立 Blog Model,並使用 Data Annotations 來指定資料型別
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace EFCoreMigration.Models
{
    public class Blog
    {
        // 透過 Data Annotations 來設定 BlogID 和 PostDate
        
        [Key]
        public int BlogID { get; set; }

        public string BlogName { get; set; }

        [Required]
        [Column(TypeName = "date")]
        public DateTime PostDate { get; set; }
    }
}
手動建立 MigrationDbContext,MigrationDbContext 繼承 DbContext,並在 OnModelCreating() 內使用 Fluent API 指定 Blog.BlogName 資料型態,連線字串部分理論上不該寫死在 Code 內,該筆記重點放在熟悉 Migration 使用,就不理會它囉
using Microsoft.EntityFrameworkCore;

namespace EFCoreMigration.Models
{
    public class MigrationDbContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Server=.;Database=EFCoreMigration;Trusted_Connection=True;TrustServerCertificate=true;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // 透過 FluentAPI 來設定資料型態
            modelBuilder.Entity<Blog>()
                .Property(p => p.BlogName)
                .HasColumnType("nvarchar")
                .HasMaxLength(100);

            base.OnModelCreating(modelBuilder);
        }
    }
}

Migration

Migration API 語法
  • Add-Migration:新增 migration 設定
  • update-database:根據 migration 設定更新資料庫
在套件管理器控制台內輸入下述語法後,專案內就會出現 Migrations 資料夾
Add-Migration InitDB

Migrations 資料夾內會有 DB Snapshot 和 InitDB 檔案


打開 InitDB Migration 檔案可以看見相關內容
using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace EFCoreMigration.Migrations
{
    /// <inheritdoc />
    public partial class InitDB : Migration
    {
        /// <inheritdoc />
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Blogs",
                columns: table => new
                {
                    BlogID = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    BlogName = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: false),
                    PostDate = table.Column<DateTime>(type: "date", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Blogs", x => x.BlogID);
                });
        }

        /// <inheritdoc />
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Blogs");
        }
    }
}
實際執行 migations 檔案至 DB  內
update-database
在 SSMS 內可以看見 EFCoreMigration DB 和 Blog Table 被建立出來啦
更改 Model Property

在 Blog Model 內新增 CreatedTimestamp Property
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace EFCoreMigration.Models
{
    public class Blog
    {
        [Key]
        public int BlogID { get; set; }

        public string BlogName { get; set; }

        [Required]
        [Column(TypeName = "date")]
        public DateTime PostDate { get; set; }

        // 新增該 Property
        public DateTime CreatedTimestamp { get; set; }

    }
}
進行 Migration 操作並更新至 DB 去
Add-Migration AddCreatedTimestamp
update-database
Migration 設定檔內容
using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace EFCoreMigration.Migrations
{
    /// <inheritdoc />
    public partial class AddCreatedTimestamp : Migration
    {
        /// <inheritdoc />
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AddColumn<DateTime>(
                name: "CreatedTimestamp",
                table: "Blogs",
                type: "datetime2",
                nullable: false,
                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
        }

        /// <inheritdoc />
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropColumn(
                name: "CreatedTimestamp",
                table: "Blogs");
        }
    }
}
在 SSMS 內就可以看見 CreateTimestamp 欄位
以上簡易紀錄 Code First Migration 流程

沒有留言:

張貼留言