Rafy 框架 - 幽靈插件(假刪除)


 

Rafy 框架又添新成員:幽靈插件。本文將解釋該插件的場景、使用方法、原理。

 

場景


在開發各類數據庫應用系統時,往往需要在刪除數據時不是真正地刪除數據,而只是把數據標識為‘已刪除’狀態。這些數據在業務邏輯上是已經完全刪除、不可用的數據,但是不能在數據庫中真正的把它們刪除,而是需要永久保留這些歷史數據。即開發人員常說的‘假刪除’功能。

這種需求往往是系統級的。往往不是針對某一張表,而很可能是針對系統中的所有表都需要實現‘假刪除’功能。

 

使用方法


由於這種需求比較常見,所以我們決定專門為該功能寫一個獨立的 Rafy 插件。這樣,開發人員需要實現假刪除功能時,只需要引用該插件后,系統中所有刪除的實體都自動變為‘幽靈’,同時這些幽靈數據在倉庫的所有查詢中都將被自動過濾。

使用步驟:

  1. 通過 Nuget Package Manager 搜索並安裝 Rafy.Domain.EntityPhantom 插件。
    nuget
  2. 在 DomainApp 中添加該插件:
    class JXCApp : DomainApp
    {
        protected override void InitEnvironment()
        {
            //添加幽靈插件到 Rafy 應用程序集中。
            RafyEnvironment.DomainPlugins.Add(new Rafy.Domain.EntityPhantom.EntityPhantomPlugin());
            RafyEnvironment.DomainPlugins.Add(new JXCPlugin());
    
            base.InitEnvironment();
        }
    }
  3. 為需要幽靈功能的實體打開該功能,需要在實體元數據配置中進行配置:
    internal class UserConfig : JXCEntityConfig<User>
    {
        protected override void ConfigMeta()
        {
            Meta.MapTable().MapAllProperties();
    
            //在實體配置中加入此行代碼,為實體啟用幽靈功能。
            Meta.EnablePhantoms();
        }
    }

 

效果


所有繼承自 Entity 的實體都會統一的添加一個 IsPhantom 的屬性。這個屬性表示這個實體是否為‘幽靈’,即已經刪除的數據。

  • 開發者可以使用 Meta.EnablePhantoms() 來為某個指定的實體類型開啟‘幽靈’功能。
  • 開啟該功能的實體的 IsPhantom 屬性會自動映射到數據庫中。
  • 在保存實體時,如果要刪除一個聚合實體,則這個聚合中的所有實體都將會被標記為‘幽靈’狀態。
  • 在查詢實體時,所有的查詢,都將會自動過濾掉所有‘幽靈’狀態的數據。(手寫 SQL 查詢的場景不在考慮范圍內。)
  • 使用批量導入數據插件進行數據的批量導入時,批量刪除的實體同樣都會被標記為‘幽靈’狀態。

運行程序后,數據庫中的字段,已經自動添加上 IsPhantom 字段了:

image

在使用 GetAll 查詢所有實體時,框架自動加上一 IsPhantom = false 的過濾條件:

SELECT *
FROM [User]
WHERE [User].[IsPhantom] = @p0
ORDER BY [User].[Id] ASC
Parameters:False

數據的刪除,變為更新表中對應行的 IsPhantom 字段為 True:

UPDATE [User] SET [Name] = @p0,[IsPhantom] = @p1 WHERE [Id] = @p2
Parameters:"Name",True,3

 

原理


幽靈插件的原理比較簡單。在 Rafy 框架的基礎上,以插件的形式對 Rafy 框架中實體的數據層進行了擴展。在啟用實體的幽靈功能后,該實體的 DataProvider 類型的 Deleting、Querying 事件都會被監聽並擴展:

/// <summary>
/// 數據的刪除、查詢的攔截器。
/// </summary>
internal static class PhantomDataInterceptor
{
    internal static void Intercept()
    {
        RepositoryDataProvider.Deleting += RepositoryDataProvider_Deleting;
        RepositoryDataProvider.Querying += RepositoryDataProvider_Querying;
    }
}

在查詢時,框架自動分析出當前查詢的 SQL 樹,並在主查詢上加上 IsPhantom = false 的過濾條件。

有興趣的同學,可以查看 Rafy 框架源碼。微笑

 

PS:該文已經納入《 Rafy 用戶手冊》中。


免責聲明!

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



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