efcore 新特性 SaveChanges Events

efcore 新特性 SaveChanges Events

Intro

昨天早上看到以前关注的一个 efcore 的 issue 被 closed ,因而看了一眼, ef core 新合并了一个 PR,在 DbContext 中增长了 SaveChanges 相关的几个事件,具体的变动能够参数 PR https://github.com/dotnet/efcore/pull/21862html

Events

以前写过两篇关于 EF Core 作自动审计的文章git

第一次的实现须要显式继承一个 AuditDbContext ,在有些须要没办法修改 DbContext 或者原有 DbContext 已经有继承某一个类,就没有办法用了,能够参考 https://www.cnblogs.com/weihanli/p/auto-audit-for-entity-framework.htmlgithub

后面结合 AOP 改进了一版,经过一个审计切面逻辑完成自动审计,可是须要引入 AOP 组件支持,对于不想引入额外组件的项目来讲也并不是特别友好,能够参考 http://www.javashuo.com/article/p-hlleaiyr-nn.html数据库

在这个 PR 合并以后,咱们能够经过 SavingChanges 事件获取保存以前 DbContext 的状态,经过 SavedChanges 事件来获取保存成功后的 DbContext 信息,SaveChangesFailed 事件获取保存失败信息ui

事件定义以下:.net

/// <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;

事件参数定义以下:code

/// <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 操做数据时自动设置更新时间等信息htm

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

Reference

相关文章
相关标签/搜索