❤️ 关注 Furion 微信公众号有惊喜哦!
🫠 遇到问题了
Skip to main content
⭐️ 开通 VIP 服务仅需 499 元/年,尊享 365 天项目无忧23 立即开通23 ⭐️
特别赞助

9.26 实体数据监听器

📝 模块更新日志
  • 问题修复

    •   EFCore 实体监听器 IEntityChangedListener 问题 4.8.1.7 ⏱️2022.11.26 #I61CTI

9.26.1 实体数据监听器

在最新的 Furion1.1.6+ 版本中,新增了 IEntityChangedListener 实体数据监听接口,可以监听 EFCore 任何实体表 增删改 操作。

9.26.2 有何作用

  • 类似数据库 触发器 功能,可实现 增删改 监听
  • 可以实现特殊操作,比如刷新缓存,记录日志等

9.26.3 如何使用

Furion 框架中,默认不启用实体数据监听器,如想启用,只需要在 数据库上下文 构造函数中启用即可:

9.26.3.1 启用数据监听

using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;

namespace Furion.EntityFramework.Core
{
[AppDbContext("Sqlite3ConnectionString")]
public class DefaultDbContext : AppDbContext<DefaultDbContext>
{
public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
{
EnabledEntityChangedListener = true;
}
}
}

9.26.3.2 监听特定实体数据

特别注意

如果实体没有直接或间接继承 Entity 或者 EntityBase,那么需要在实体中添加 __State__ 非公开属性,如:

internal EntityState __State__ { get; set; }
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;

namespace Furion.Core
{
public class Post : Entity, IEntityChangedListener<Post>
{
/// <summary>
/// 构造函数
/// </summary>
public Post()
{
CreatedTime = DateTimeOffset.UtcNow;
IsDeleted = false;
}

/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }

/// <summary>
/// Person 集合
/// </summary>
public ICollection<Person> Persons { get; set; }

/// <summary>
/// 实体更改后触发
/// </summary>
/// <param name="entity">新数据</param>
/// <param name="oldEntity">旧数据</param>
/// <param name="dbContext">数据库上下文</param>
/// <param name="dbContextLocator">数据库上下文定位器</param>
/// <param name="state">实体状态</param>
public void OnChanged(Post entity, Post oldEntity, DbContext dbContext, Type dbContextLocator, EntityState state)
{
// 刷新缓存
App.GetService<IMemoryCache>().Set("Key", "Value");
}
}
}

9.26.4 IEntityChangedListener 定义

/// <summary>
/// 实体数据改变监听依赖接口
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public interface IEntityChangedListener<TEntity>
where TEntity : class, IPrivateEntity, new()
{
/// <summary>
/// 监听数据改变之前(仅支持EFCore操作)
/// </summary>
/// <param name="entity"></param>
/// <param name="dbContext"></param>
/// <param name="dbContextLocator"></param>
/// <param name="state"></param>
void OnChanging(TEntity entity, DbContext dbContext, Type dbContextLocator, EntityState state) { }

/// <summary>
/// 监听数据改变之后(仅支持EFCore操作)
/// </summary>
/// <param name="newEntity">新值</param>
/// <param name="oldEntity">旧值</param>
/// <param name="dbContext"></param>
/// <param name="dbContextLocator"></param>
/// <param name="state"></param>
void OnChanged(TEntity newEntity, TEntity oldEntity, DbContext dbContext, Type dbContextLocator, EntityState state);

/// <summary>
/// 监听数据改变失败(仅支持EFCore操作)
/// </summary>
/// <param name="entity"></param>
/// <param name="dbContext"></param>
/// <param name="dbContextLocator"></param>
/// <param name="state"></param>
void OnChangeFailed(TEntity entity, DbContext dbContext, Type dbContextLocator, EntityState state) { }
}

9.26.5 [SuppressChangedListener] 跳过监听

默认情况下,Furion 框架会对所有新增、更新、编辑的实体进行监听,有些时候我们无需监听特定实体,只需要在实体上贴 [SuppressChangedListener] 特性即可。

9.26.6 反馈与建议

与我们交流

给 Furion 提 Issue