在FreeSQL中實現「觸發器」和軟刪除功能

前言

最近做新項目,技術棧 AspNetCore + FreeSQL

這個ORM真的好用,文檔也很完善,這裡記錄一下兩個有關「觸發器」的功能實現

修改實體時記錄更新時間

模型程式碼

我的模型都是基於這個 ModelBase 派生的,自帶三個屬性欄位

public abstract class ModelBase : ISoftDelete {
    public DateTime CreatedTime { get; set; } = DateTime.Now;
    public DateTime ModifiedTime { get; set; } = DateTime.Now;
    public bool IsDeleted { get; set; } = false;
}

現在要實現修改每個實體的時候自動更新 ModifiedTime 欄位

可以使用 FreeSQL 提供的 AOP 里的「審計屬性值」功能

按照官方的介紹:該功能可以實現插入/更新時統一處理某些值,比如某屬性的雪花演算法值、創建時間值、甚至是業務值。

創建FreeSQL實例的時候配置一下

檢查實體類型,如果是 ModelBase 類型的話,那麼把 ModifiedTime 欄位設置為當前修改的時間

// 實體變化事件監聽
freeSql.Aop.AuditValue += (sender, args) => {
    if (args.Object is ModelBase modelBase) {
        modelBase.ModifiedTime = DateTime.Now;
    }
};

除此之外,還有一個功能是監控實體修改的,我一開始用的這個,但是發現它是在實體已經修改保存完才執行,無法實現記錄更新時間的功能。不過這個用來審計是比較有用的,記錄一下~

fsql.Aop.CurdAfter += (s, e) => {
    Console.WriteLine($"ManagedThreadId:{Thread.CurrentThread.ManagedThreadId};"+
    $" FullName:{e.EntityType.FullName} ElapsedMilliseconds:{e.ElapsedMilliseconds}ms, {e.Sql}");
};

實現軟刪除

現在的設計為了提高容錯性都是做軟刪除,這樣誤刪之後還能恢複數據。

我之前封裝的 DjangoStarter 框架是自己實現了軟刪除(通過重寫 DjangoORM 的 objects 管理器實現)

來到 FreeSQL 這裡,根據官方文檔,可以直接使用過濾器功能實現軟刪除。

先定義一個介面

public interface ISoftDelete {
    bool IsDeleted { get; set; }
}

其實用我上面的 ModelBase 也行

不過我看官方文檔這麼用了,也就跟著寫~ (介面的泛用性更高,可能有些實體是不需要創建時間和修改時間欄位的)

然後在創建FreeSQL實例的時候配置一下

freeSql.GlobalFilter.Apply<ISoftDelete>("IsDeleted", a => a.IsDeleted == false);

這樣讀取數據的時候,IsDeleted 欄位為 true 的項目就自動過濾掉了

刪除的時候不要直接執行 repo.Delete ,而是把 IsDeleted 欄位設置為 true

當然也可以像上面的 AOP 一樣,把所有刪除操作攔截下來。

參考資料