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 事件获取保存失败事件

事件定义如下:


/// <summary>
/// An event fired at the beginning of a call to <see cref="M:SaveChanges"/> or <see cref="M:SaveChangesAsync"/>
/// </summary>
public event EventHandler<SavingChangesEventArgs> SavingChanges; /// <summary>
/// An event fired at the end of a call to <see cref="M:SaveChanges"/> or <see cref="M:SaveChangesAsync"/>
/// </summary>
public event EventHandler<SavedChangesEventArgs> SavedChanges; /// <summary>
/// An event fired if a call to <see cref="M:SaveChanges"/> or <see cref="M:SaveChangesAsync"/> fails with an exception.
/// </summary>
public event EventHandler<SaveChangesFailedEventArgs> SaveChangesFailed;

事件参数定义如下:

/// <summary>
/// Base event arguments for the <see cref="M:DbContext.SaveChanges" /> and <see cref="M:DbContext.SaveChangesAsync" /> events.
/// </summary>
public abstract class SaveChangesEventArgs : EventArgs
{
/// <summary>
/// Creates a base event arguments instance for <see cref="M:DbContext.SaveChanges" />
/// or <see cref="M:DbContext.SaveChangesAsync" /> events.
/// </summary>
/// <param name="acceptAllChangesOnSuccess"> The value passed to SaveChanges. </param>
protected SaveChangesEventArgs(bool acceptAllChangesOnSuccess)
{
AcceptAllChangesOnSuccess = acceptAllChangesOnSuccess;
} /// <summary>
/// The value passed to <see cref="M:DbContext.SaveChanges" /> or <see cref="M:DbContext.SaveChangesAsync" />.
/// </summary>
public virtual bool AcceptAllChangesOnSuccess { get; }
} /// <summary>
/// Event arguments for the <see cref="DbContext.SavingChanges" /> event.
/// </summary>
public class SavingChangesEventArgs : SaveChangesEventArgs
{
/// <summary>
/// Creates event arguments for the <see cref="M:DbContext.SavingChanges" /> event.
/// </summary>
/// <param name="acceptAllChangesOnSuccess"> The value passed to SaveChanges. </param>
public SavingChangesEventArgs(bool acceptAllChangesOnSuccess)
: base(acceptAllChangesOnSuccess)
{
}
} /// <summary>
/// Event arguments for the <see cref="DbContext.SavedChanges" /> event.
/// </summary>
public class SavedChangesEventArgs : SaveChangesEventArgs
{
/// <summary>
/// Creates a new <see cref="SavedChangesEventArgs" /> instance with the given number of entities saved.
/// </summary>
/// <param name="acceptAllChangesOnSuccess"> The value passed to SaveChanges. </param>
/// <param name="entitiesSavedCount"> The number of entities saved. </param>
public SavedChangesEventArgs(bool acceptAllChangesOnSuccess, int entitiesSavedCount) : base(acceptAllChangesOnSuccess)
{
EntitiesSavedCount = entitiesSavedCount;
} /// <summary>
/// The number of entities saved.
/// </summary>
public virtual int EntitiesSavedCount { get; }
} /// <summary>
/// Event arguments for the <see cref="DbContext.SaveChangesFailed" /> event.
/// </summary>
public class SaveChangesFailedEventArgs : SaveChangesEventArgs
{
/// <summary>
/// Creates a new <see cref="SaveChangesFailedEventArgs"/> instance with the exception that was thrown.
/// </summary>
/// <param name="acceptAllChangesOnSuccess"> The value passed to SaveChanges. </param>
/// <param name="exception"> The exception thrown. </param>
public SaveChangesFailedEventArgs(bool acceptAllChangesOnSuccess, [NotNull] Exception exception)
: base(acceptAllChangesOnSuccess)
{
Exception = exception;
} /// <summary>
/// The exception thrown during<see cref="M:DbContext.SaveChanges"/> or <see cref="M:DbContext.SaveChangesAsync"/>.
/// </summary>
public virtual Exception Exception { get; }
}

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. 数据可视化之分析篇(四)PowerBI分析模型:产品关联度分析

    https://zhuanlan.zhihu.com/p/64510355 逛超市的时候,面对货架上琳琅满目的商品,你会觉得这些商品的摆放,或者不同品类的货架分布是随机排列的吗,当然不是. 应该都听说 ...

  2. python 面向对象专题(四):封装、多态、鸭子类型、类的约束、super

    https://www.cnblogs.com/liubing8/p/11321099.html 目录 Python面向对象04 /封装.多态.鸭子类型.类的约束.super 1. 封装 2. 多态 ...

  3. hihoCoder 1052 基因工程 最详细的解题报告

    题目来源:基因工程 解题思路:假设基因序列长度为N,则需要计算基因序列前K个和后K个相同所需要的最少改变次数sum. 假设基因序列为 ATACGTCT (即M=8),K=6:interval=M-K= ...

  4. MySQL 面试题 24 问

    MySQL 是数据库中的主流中的主流,小中性公司基本都以它为主,而作为后端开发和数据库工程师来说,MySQL 是面试必须要过的一关.以下是小编整理网络的 MySQL 面试高频题,希望对大家有所帮助. ...

  5. easyui获取datagrid中的某一列的所有值

    function getCol(){ var rows = $("#dg").datagrid("getRows"); var total = "&q ...

  6. Windows 磁盘分区后如何再合并&如何用Windows自带工具扩大某个分区

    Windows 磁盘分区后如何再合并&用Windows自带工具扩大某个分区 注:此方法有一定的成功率,更加完善可行的方法请看http://www.diskgenius.cn/help/part ...

  7. 【Docker】Redis 安装使用教程

    1.安装 1.1 拉取镜像 docker pull redis redis:4.0 1.2 创建redis容器名"redistest1",并开启持久化 docker run -d ...

  8. jmeter压力测试报错:java.net.BindException: Address already in use: connect || java.net.SocketException: Socket closed

    windows提供给TCP/IP链接的端口为 1024-5000,并且要四分钟来循环回收它们,就导致我们在短时间内跑大量的请求时将端口占满了,导致如上报错. 解决办法(在jmeter所在服务器操作): ...

  9. 获取DataGridview中某列的所有数据

    /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam& ...

  10. node的async模块

    废话不多说,直接开始 这个模块有几种方法.分别用于的不通的情况自己喜欢怎么用就怎么用 第一个方法,series  这个方法用于串行切无关联.什么意思那就是,里面的方法是一个一个执行的,每一个方法相互不 ...