前言

最近做新项目,技术栈 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 一样,把所有删除操作拦截下来。

参考资料

在FreeSQL中实现「触发器」和软删除功能的更多相关文章

  1. 在Mac中使用「dd」指令烧录ISO镜像文件到U盘

    作者:超級efly   發布:2014-07-26 20:22   分類:電腦   閱讀:442   11條評論    大家在Windows系統下可以方便的使用UltraISO程式來燒錄「.ISO」, ...

  2. nc - 网络工具箱中的「瑞士军刀」

    nc 是 Linux下强大的网络命令行工具,主要用于 TCP.UDP.UNIX域套接字 相关的操作 它被设计成可以由其他程序灵活驱动可靠的后台工具,拥有 "瑞士军刀" 的美称,每个 ...

  3. Facebook 发布「流程」

    时不时就会在面试过程中碰到有候选人问 Facebook 是否采用 Scrum 之类的敏捷方法,偶尔也会有中国的朋友问及 Facebook 上线流程.我通常会简单说几句,然后说「如果你真感兴趣的话,去搜 ...

  4. 「技巧」如何快速安装 Sketch 插件

    Sketch拥有强大丰富的插件,但是这些插件天各一方,四处查找下载地址非常麻烦.这里提供一个技巧,通过一个入口可以安装各种插件,基本涵盖了市面上所有靠谱的插件. 准备 Sketch54 Runner ...

  5. spring cloud 入门,看一个微服务框架的「五脏六腑」

    Spring Cloud 是一个基于 Spring Boot 实现的微服务框架,它包含了实现微服务架构所需的各种组件. 注:Spring Boot 简单理解就是简化 Spring 项目的搭建.配置.组 ...

  6. 从 Spring Cloud 看一个微服务框架的「五脏六腑」

    原文:https://webfe.kujiale.com/spring-could-heart/ Spring Cloud 是一个基于 Spring Boot 实现的微服务框架,它包含了实现微服务架构 ...

  7. Linux 小知识翻译 - 「BitTorrent」

    这次聊聊「BitTorrent」. (也就是下片子的 BT) BitTorrent是文件传输的一种.它可以在服务端负担很小的情况下高速的传输文件. BitTorrent最大的特点就是服务端可以将文件的 ...

  8. Linux 小知识翻译 - 「别名」

    实际上,「别名」被用在多种场合下.比如「命令的别名」,「邮件地址的别名」等等. 所以,单独说「别名」的时候,根据不用的场合,代表的意思也不一样. 一般来说,「别名」是指意思差不多的东西. 「别名」的英 ...

  9. Linux 小知识翻译 - 「分区」

    安装Linux的时候,需要对硬盘进行分区.那么「分区」到底是什么呢? 「分区」在日语中有区分,分割的意思.计算机术语中有时会说「对一个磁盘进行分区」,整个意思就是指定如何分割磁盘的意思. 「对磁盘进行 ...

随机推荐

  1. Java开发学习(二十六)----SpringMVC返回响应结果

    SpringMVC接收到请求和数据后,进行了一些处理,当然这个处理可以是转发给Service,Service层再调用Dao层完成的,不管怎样,处理完以后,都需要将结果告知给用户. 比如:根据用户ID查 ...

  2. Dynamic CRM插件中记录日志-Nlog记录到文本

    Dynamic CRM插件中记录日志的方式有多种 通常情况下分为ITracingService记录.单独日志表插入记录.文本记录三种. 之前整理过ITracingService记录的方式,但这种记录有 ...

  3. setContentView源码分析

    当我们在Activity中调用setContentView,它到底做了什么呢 override fun onCreate(savedInstanceState: Bundle?) { super.on ...

  4. e1000e网卡驱动在麒麟3.2.5上编译安装

    一.清空原驱动 因为系统安装完毕后系统中自带了e1000e的网卡驱动,会影响后面自行编译的驱动 所以先用find命令找出并删除掉所有关于e1000e的驱动文件 find / -name "* ...

  5. Vite+React搭建开发构建环境实践

    前言 使用 Vite 已经有两年了,期间使用它开发过单页面应用,也开发过浏览器扩展插件,对比日常工作中用到的 webpack 构建速度大幅提升,开发体验也好很多. 虽然相比于 webpack 来说简单 ...

  6. [Golang] GO 语言工作环境的基本概念

    1. GOPATH 和 GOROOT(环境变量) 1. GOROOT go 编译器.标准库等安装的地方,所有我们写的代码其实都是文本文件而已,需要编译器等工具将其加工成可执行文件或者库文件才能使用,每 ...

  7. Kubernetes实践技巧:集群升级k8s版本

    更新证书 使用 kubeadm 安装 kubernetes 集群非常方便,但是也有一个比较烦人的问题就是默认的证书有效期只有一年时间,所以需要考虑证书升级的问题,本文的演示集群版本为 v1.16.2 ...

  8. Solutions:如何运用Elastic App Search快速建立出色的React搜索体验

    建立搜索体验是一项艰苦的工作. 乍一看似乎很容易:建立一个搜索栏,将数据放入数据库,然后让用户输入对该数据库的查询. 但是,在数据建模,底层逻辑以及(当然)总体设计和用户体验方面,有很多事情要考虑. ...

  9. Prometheus组件介绍

    Prometheus Server Prometheus Server是Prometheus组件中的核心部分,负责实现对监控数据的获取,存储以及查询. Prometheus Server可以通过静态配 ...

  10. python 代码执行顺序

    Python代码在执行过程中,遵循下面的基本原则: 普通语句,直接执行: 碰到函数,将函数体载入内存,并不直接执行 碰到类,执行类内部的普通语句,但是类的方法只载入,不执行 碰到if.for等控制语句 ...