efcore 新特性 SaveChanges Events

Intro

昨天早上看到之前关注的一个 efcore 的 issue 被 closed ,于是看了一眼, ef core 新合并了一个 PR,在 DbContext 中增加了 SaveChanges 相关的几个事件,具体的变更可以参数 PR https://github.com/dotnet/efcore/pull/21862

Events

之前写过两篇关于 EF Core 做自动审计的文章,但是不够灵活

第一次的实现需要显示继承一个 AuditDbContext ,在有些需要没办法修改 DbContext 或者原有 DbContext 已经有继承某一个类,就没有办法用了

后面使用 AOP 改进了一版,通过一个审计切面逻辑完整自动审计,但是需要引入 AOP 组件支持,对于不想引入额外组件的项目来说也并非特别友好

在这个变更之后,我们可以通过 SavingChanges 事件获取保存之前 DbContext 的状态,通过 SavedChanges 事件来获取保存成功的事件,SaveChangesFailed 事件获取保存失败事件

事件定义如下:


  1. /// <summary>
  2. /// An event fired at the beginning of a call to <see cref="M:SaveChanges"/> or <see cref="M:SaveChangesAsync"/>
  3. /// </summary>
  4. public event EventHandler<SavingChangesEventArgs> SavingChanges;
  5. /// <summary>
  6. /// An event fired at the end of a call to <see cref="M:SaveChanges"/> or <see cref="M:SaveChangesAsync"/>
  7. /// </summary>
  8. public event EventHandler<SavedChangesEventArgs> SavedChanges;
  9. /// <summary>
  10. /// An event fired if a call to <see cref="M:SaveChanges"/> or <see cref="M:SaveChangesAsync"/> fails with an exception.
  11. /// </summary>
  12. public event EventHandler<SaveChangesFailedEventArgs> SaveChangesFailed;

事件参数定义如下:

  1. /// <summary>
  2. /// Base event arguments for the <see cref="M:DbContext.SaveChanges" /> and <see cref="M:DbContext.SaveChangesAsync" /> events.
  3. /// </summary>
  4. public abstract class SaveChangesEventArgs : EventArgs
  5. {
  6. /// <summary>
  7. /// Creates a base event arguments instance for <see cref="M:DbContext.SaveChanges" />
  8. /// or <see cref="M:DbContext.SaveChangesAsync" /> events.
  9. /// </summary>
  10. /// <param name="acceptAllChangesOnSuccess"> The value passed to SaveChanges. </param>
  11. protected SaveChangesEventArgs(bool acceptAllChangesOnSuccess)
  12. {
  13. AcceptAllChangesOnSuccess = acceptAllChangesOnSuccess;
  14. }
  15. /// <summary>
  16. /// The value passed to <see cref="M:DbContext.SaveChanges" /> or <see cref="M:DbContext.SaveChangesAsync" />.
  17. /// </summary>
  18. public virtual bool AcceptAllChangesOnSuccess { get; }
  19. }
  20. /// <summary>
  21. /// Event arguments for the <see cref="DbContext.SavingChanges" /> event.
  22. /// </summary>
  23. public class SavingChangesEventArgs : SaveChangesEventArgs
  24. {
  25. /// <summary>
  26. /// Creates event arguments for the <see cref="M:DbContext.SavingChanges" /> event.
  27. /// </summary>
  28. /// <param name="acceptAllChangesOnSuccess"> The value passed to SaveChanges. </param>
  29. public SavingChangesEventArgs(bool acceptAllChangesOnSuccess)
  30. : base(acceptAllChangesOnSuccess)
  31. {
  32. }
  33. }
  34. /// <summary>
  35. /// Event arguments for the <see cref="DbContext.SavedChanges" /> event.
  36. /// </summary>
  37. public class SavedChangesEventArgs : SaveChangesEventArgs
  38. {
  39. /// <summary>
  40. /// Creates a new <see cref="SavedChangesEventArgs" /> instance with the given number of entities saved.
  41. /// </summary>
  42. /// <param name="acceptAllChangesOnSuccess"> The value passed to SaveChanges. </param>
  43. /// <param name="entitiesSavedCount"> The number of entities saved. </param>
  44. public SavedChangesEventArgs(bool acceptAllChangesOnSuccess, int entitiesSavedCount) : base(acceptAllChangesOnSuccess)
  45. {
  46. EntitiesSavedCount = entitiesSavedCount;
  47. }
  48. /// <summary>
  49. /// The number of entities saved.
  50. /// </summary>
  51. public virtual int EntitiesSavedCount { get; }
  52. }
  53. /// <summary>
  54. /// Event arguments for the <see cref="DbContext.SaveChangesFailed" /> event.
  55. /// </summary>
  56. public class SaveChangesFailedEventArgs : SaveChangesEventArgs
  57. {
  58. /// <summary>
  59. /// Creates a new <see cref="SaveChangesFailedEventArgs"/> instance with the exception that was thrown.
  60. /// </summary>
  61. /// <param name="acceptAllChangesOnSuccess"> The value passed to SaveChanges. </param>
  62. /// <param name="exception"> The exception thrown. </param>
  63. public SaveChangesFailedEventArgs(bool acceptAllChangesOnSuccess, [NotNull] Exception exception)
  64. : base(acceptAllChangesOnSuccess)
  65. {
  66. Exception = exception;
  67. }
  68. /// <summary>
  69. /// The exception thrown during<see cref="M:DbContext.SaveChanges"/> or <see cref="M:DbContext.SaveChangesAsync"/>.
  70. /// </summary>
  71. public virtual Exception Exception { get; }
  72. }

More

除了上面的审计,你也可以使用通过这些事件,实现保存之前的自动更新数据库字段的值,比如 AddUpdate 操作数据时自动设置更新时间等信息

本文提到的特性还未正式发布,预计会在 .net5 下一个预览版中发布,如果想现在要尝试,请使用 efcore 的 daily build 的包,可以参考 https://github.com/dotnet/aspnetcore/blob/master/docs/DailyBuilds.md

Reference

efcore 新特性 SaveChanges Events的更多相关文章

  1. EFCore 5 新特性 `SaveChangesInterceptor`

    EFCore 5 新特性 SaveChangesInterceptor Intro 之前 EF Core 5 还没正式发布的时候有发布过一篇关于 SaveChangesEvents 的文章,有需要看可 ...

  2. Java8 新特性之Stream----java.util.stream

    这个包主要提供元素的streams函数操作,比如对collections的map,reduce. 例如: int sum = widgets.stream() .filter(b -> b.ge ...

  3. EFCore 5 新特性 —— Savepoints

    EFCore 5 中的 Savepoints Intro EFCore 5中引入了一个新特性,叫做 Savepoints,主要是事务中使用,个人感觉有点类似于 Windows 上的系统还原点,如果事务 ...

  4. 【译】Meteor 新手教程:在排行榜上添加新特性

    原文:http://danneu.com/posts/6-meteor-tutorial-for-fellow-noobs-adding-features-to-the-leaderboard-dem ...

  5. JDK各个版本的新特性jdk1.5-jdk8

    JDK各个版本的新特性 对于很多刚接触java语言的初学者来说,要了解一门语言,最好的方式就是要能从基础的版本进行了解,升级的过程,以及升级的新特性,这样才能循序渐进的学好一门语言.今天先为大家介绍一 ...

  6. JDK各版本新特性!

    1.JDK1.5 新特性 1.自动装箱与拆箱:自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中.自动拆箱的过程:每当需要一个值时,被装箱对象中的值就被自动地提取 ...

  7. iOS开发实用技巧—项目新特性页面的处理

    iOS开发实用技巧篇—项目新特性页面的处理 说明:本文主要说明在项目开发中会涉及到的最最简单的新特性界面(实用UIScrollView展示多张图片的轮播)的处理. 代码示例: 新建一个专门的处理新特性 ...

  8. HTML5新特性及详解

    什么是HTML5:HTML5 是下一代的HTML,将成为 HTML.XHTML 以及 HTML DOM 的新标准. 为 HTML5 建立的一些规则: 新特性应该基于 HTML.CSS.DOM 以及 J ...

  9. Java8 十大新特性详解(转)

    本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口 ...

随机推荐

  1. requests接口自动化8-传递数据为xml形式的post请求:data

    传递数据为xml形式的post请求 请求体内容: <?xml version=“1.0” encoding = “UTF-8”?> <COM> <REQ name=&qu ...

  2. Mysql基础(六):索引、数据库备份、锁和事务、慢查询优化、索引命中相关

    目录 数据库05 /索引.数据库备份.锁和事务.慢查询优化.索引命中相关 1. 什么是索引 2. 索引的原理 3. 索引的数据结构(聚集索引.辅助索引) 4. 索引操作 5. 索引的两大类型hash与 ...

  3. 数据可视化之DAX篇(十)在PowerBI中累计求和的两种方式

    https://zhuanlan.zhihu.com/p/64418286 假设有一组数据, 已知每一个产品贡献的利润,如果要计算前几名产品的贡献利润总和,或者每一个产品和利润更高产品的累计贡献占总体 ...

  4. Mysql----左连接、右连接、内连接、全连接的区别

    最近,突然想起来数据库有好些时间没用到,所以,想把数据库有关的知识回顾一下,所以接下来这个月,基本上会以数据库的帖子来写为主,首先,很多同学都会有个错觉,觉得学习数据库会sql语句的增删改查就够了,其 ...

  5. day1 python计算器底层运作,注释及变量

    每日一记 utf-8 国际标准编码(可变长的unicode编码)中文3字节,英文数字特殊字符1字节 gbk 中国标准编码 中文2字节,英文数字特殊字符1字节 1.原码,反码,补码 "&quo ...

  6. Sequential Minimal Optimization: A Fast Algorithm for Training Support Vector Machines 论文研读

    摘要 本文提出了一种用于训练支持向量机的新算法:序列最小优化算法(SMO).训练支持向量机需要解决非常大的二 次规划(QP)优化问题.SMO 将这个大的 QP 问题分解为一系列最小的 QP 问题.这些 ...

  7. Oracle基础概述

    本部分主要参考”风哥“的Oracle入门视频. 一.体系结构概述 1.物理结构(文件结构) Oracle有四种文件:控制文件.数据文件.日志文件.参数文件 其中日志文件分为两类:联机日志文件.归档日志 ...

  8. Vuex与axios的封装和调用

    Vuex状态管理 状态就是数据.    在react里有个Flux的数据流管理(单向数据流) 作用1:实现组件之间的数据共享. 作用2:用于缓存.(避免当用户频繁点击,页面不断调接口)     先安装 ...

  9. 入门大数据---Hive计算引擎Tez简介和使用

    一.前言 Hive默认计算引擎时MR,为了提高计算速度,我们可以改为Tez引擎.至于为什么提高了计算速度,可以参考下图: 用Hive直接编写MR程序,假设有四个有依赖关系的MR作业,上图中,绿色是Re ...

  10. java基础知识--数据类型

    计算机时识别不了我们编写的代码语言,计算机中的数据全部采用二进制表示,即0和1表示的数字,每一个0或者1就是一个位,一个位叫做一个bit(比特).(实际上计算机只能识别高低电平,而不是0和1.) 字节 ...