efcore 新特性 SaveChanges Events
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 组件支持,对于不想引入额外组件的项目来说也并非特别友好,可以参考
在这个 PR 合并之后,我们可以通过 SavingChanges 事件获取保存之前 DbContext 的状态,通过 SavedChanges 事件来获取保存成功后的 DbContext 信息,SaveChangesFailed 事件获取保存失败信息
事件定义如下:
///
/// An event fired at the beginning of a call to or
///
public event EventHandler SavingChanges;
///
/// An event fired at the end of a call to or
///
public event EventHandler SavedChanges;
///
/// An event fired if a call to or fails with an exception.
///
public event EventHandler SaveChangesFailed;
事件参数定义如下:
///
/// Base event arguments for the and events.
///
public abstract class SaveChangesEventArgs : EventArgs
{
///
/// Creates a base event arguments instance for
/// or events.
///
/// The value passed to SaveChanges.
protected SaveChangesEventArgs(bool acceptAllChangesOnSuccess)
{
AcceptAllChangesOnSuccess = acceptAllChangesOnSuccess;
}
///
/// The value passed to or .
///
public virtual bool AcceptAllChangesOnSuccess { get; }
}
///
/// Event arguments for the event.
///
public class SavingChangesEventArgs : SaveChangesEventArgs
{
///
/// Creates event arguments for the event.
///
/// The value passed to SaveChanges.
public SavingChangesEventArgs(bool acceptAllChangesOnSuccess)
: base(acceptAllChangesOnSuccess)
{
}
}
///
/// Event arguments for the event.
///
public class SavedChangesEventArgs : SaveChangesEventArgs
{
///
/// Creates a new instance with the given number of entities saved.
///
/// The value passed to SaveChanges.
/// The number of entities saved.
public SavedChangesEventArgs(bool acceptAllChangesOnSuccess, int entitiesSavedCount) : base(acceptAllChangesOnSuccess)
{
EntitiesSavedCount = entitiesSavedCount;
}
///
/// The number of entities saved.
///
public virtual int EntitiesSavedCount { get; }
}
///
/// Event arguments for the event.
///
public class SaveChangesFailedEventArgs : SaveChangesEventArgs
{
///
/// Creates a new instance with the exception that was thrown.
///
/// The value passed to SaveChanges.
/// The exception thrown.
public SaveChangesFailedEventArgs(bool acceptAllChangesOnSuccess, [NotNull] Exception exception)
: base(acceptAllChangesOnSuccess)
{
Exception = exception;
}
///
/// The exception thrown during or .
///
public virtual Exception Exception { get; }
}
More
除了上面的审计,你也可以使用通过这些事件,实现保存之前的自动更新数据库字段的值,比如 Add 或 Update 操作数据时自动设置更新时间等信息
本文提到的特性还未正式发布,预计会在 .net5 下一个预览版中发布,如果想现在要尝试,请使用 efcore 的 daily build 的包,可以参考 https://github.com/dotnet/aspnetcore/blob/master/docs/DailyBuilds.md
Reference
- https://github.com/dotnet/efcore/issues/15910
- https://github.com/dotnet/efcore/pull/21862