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 框架源码。微笑



本文转自BloodyAngel博客园博客,原文链接:http://www.cnblogs.com/zgynhqf/p/5086644.html,如需转载请自行联系原作者

相关文章
|
24天前
|
Java
提高代码质量的秘诀:类、方法、字段和包注释
提高代码质量的秘诀:类、方法、字段和包注释
40 0
|
7月前
|
JavaScript 前端开发 Java
前端项目里常见的十种报错及其解决办法
前端项目里常见的十种报错及其解决办法
184 0
|
SQL 数据库
CRUP为后面使用框架在页面上增删改查做下铺垫.(一)
CRUP为后面使用框架在页面上增删改查做下铺垫.(一)
118 0
CRUP为后面使用框架在页面上增删改查做下铺垫.(一)
CRUP为后面使用框架在页面上增删改查做下铺垫.(二)
CRUP为后面使用框架在页面上增删改查做下铺垫.(二)
75 0
|
Web App开发 Java Windows
JNA 实际开发中若干问题解决方法
JNA 实际开发中若干问题解决方法
9316 0
|
JSON 数据可视化 JavaScript
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(一)
UI库提供了很多组件,组件又带有很多属性,有一些常用属性我们可以记住并且手撸,但是有些不常用的属性,或者需要设置多个属性,这样的情况下写起来就麻烦了,有时候还要打开帮助文档看看属性是怎么设定的,需要设置什么样的属性值。那么有没有优雅的方式来设置组件的各种属性呢?我做了一个在线小工具,可以方便的设置属性,并且可以实时看到效果。
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(一)
|
JSON JavaScript 数据可视化
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(二)
UI库提供了很多组件,组件又带有很多属性,有一些常用属性我们可以记住并且手撸,但是有些不常用的属性,或者需要设置多个属性,这样的情况下写起来就麻烦了,有时候还要打开帮助文档看看属性是怎么设定的,需要设置什么样的属性值。那么有没有优雅的方式来设置组件的各种属性呢?我做了一个在线小工具,可以方便的设置属性,并且可以实时看到效果。
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(二)
|
Shell Windows
缺少对象 WScript 问题解决方法
方法一: 先把脚本保存起来(保证你的脚本能正确运行),例如命名为test.vbs 然后在QTP写以下脚本就可以正确运行了! Dim oShell Set oShell =CreateObject ("WSCript.shell") oShell.run "cmd /K wscript e:\test.vbs" Set oShell = Nothing    方法二: 首先要明白 WScript.CreateObject 和 CreateObject 的区别。
2191 0
|
JavaScript 前端开发 缓存