demoshop

demo, trying to be the best_

部分系統對於歷程是很在乎的,Before After 的記錄往往是抓鬼的好幫手,以前我們多多少少都會自行開發類似的 Log 機制,不過如果你的需求沒有很特別,倒是可以試試看這套 AutoHistory 簡單的完成這需求。

AutoHistory 使用 json 來記錄AB值,再開始設定之前必須要先新增專用的 Table 讓它存放,以下為建立指令。

CodeFirst
migrationBuilder.CreateTable(
                name: "AutoHistory",
                columns: table => new
                {
                    Id = table.Column<int>(nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                    RowId = table.Column<string>(maxLength: 50, nullable: false),
                    TableName = table.Column<string>(maxLength: 128, nullable: false),
                    Changed = table.Column<string>(nullable: true),
                    Kind = table.Column<int>(nullable: false),
                    Created = table.Column<DateTime>(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_AutoHistory", x => x.Id);
                });
T-SQL
CREATE TABLE [dbo].[AutoHistory](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[RowId] [nvarchar](50) NOT NULL,
	[TableName] [nvarchar](128) NOT NULL,
	[Changed] [nvarchar](max) NULL,
	[Kind] [int] NOT NULL,
	[Created] [datetime] NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

建立好專屬資料表後,您只需要四個步驟:

使用 NuGet 安裝 AutoHistory 

PM> Install-Package Microsoft.EntityFrameworkCore.AutoHistory

 啟用 AutoHistory

開啟你的 DbContext 檔案,找到 OnModelCreating方法,加入以下 Code

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // 啟用 auto history functionality.
        modelBuilder.EnableAutoHistory();
    }

如果你的 OnModelCreating已經有一堆設定了,可以利用以下技巧抽出來 

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Supplier>(entity =>
    {
        entity.Property(e => e.Id).ValueGeneratedNever();

        entity.Property(e => e.City)
            .IsRequired()
            .HasMaxLength(50);

        entity.Property(e => e.Name)
            .IsRequired()
            .HasMaxLength(50);

        entity.Property(e => e.Region)
            .IsRequired()
            .HasMaxLength(50);
    });
//以上是 Code First 的設定,下方是我們增加的方法
    OnModelCreatingPartial(modelBuilder);
}

partial void OnModelCreatingPartial(ModelBuilder modelBuilder);

再利用 DbContext 是 Partial class 的特性,在另外的檔案啟用 AutoHistory   

public partial class FixlionContext : DbContext
{
    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        modelBuilder.EnableAutoHistory(2048);
    }
}
觸發 AutoHistory

EntityFramework core 資料庫異動都會呼叫 SaveChangesAsync 方法,我們就在這裡觸發 AutoHistory 即可

public async ValueTask<int> SaveChangesAsync(bool ensureAutoHistory = false)
{
    if (ensureAutoHistory)
    {
        _context.EnsureAutoHistory();
    }

    return await _context.SaveChangesAsync();
}

  當你有啟用 AutoHistory 並且是「UPDATE」或「DELETE」就會自動記錄 AB 值啦。,記錄的資料如下表

如果還有額外的資料想要紀錄也是可以擴充的

db.EnsureAutoHistory(() => new CustomAutoHistory()
                    {
                        CustomField = "CustomValue"
                    });

實際使用過後,覺得其實也還滿方便的,如果你需要 AB值但還不知道要怎麼用,不妨先遵循最小可行性的原則,先使用 AutoHistory 檔者用,當系統成長到需要相當程度客制化 Log 的時候再自行開發。

 

回應討論