打造更好用的 EF 自动审计
打造更好用的 EF 自动审计
Intro
上次基于 EF Core 实现了一个自动审计的功能,详细可以参考 https://www.cnblogs.com/weihanli/p/auto-audit-for-entity-framework.html ,虽然说多数情况下可以适用,但是因为要显式继承于一个 AuditDbContextBase
或 AuditDbContext
,所以对代码的侵入性比较强,对于已经无法修改的代码或者已经继承于某一个类了,就无法再继承 AuditDBContext
了,就没有办法实现自动审计了,在 WeihanLi.EntityFramework
1.7.0 新版本里引入了 AOP 的设计,结合 AOP 来实现就简单很多了,不再需要对原有的 DbContext
有任何修改就可以轻松实现自动审计了,下面来看如何做
实例演示
服务注册
使用 AddProxyDbContext
代替 AddDbContext
,AddProxyDbContextPool
代替 AddDbContextPool
,会自动注册代理服务,以实现 AOP 拦截
var services = new ServiceCollection();
// 使用内置的扩展注册 DbContext 代理服务
//services.AddProxyDbContext<TestDbContext>(options =>
//{
// options
// .UseLoggerFactory(loggerFactory)
// //.EnableDetailedErrors()
// //.EnableSensitiveDataLogging()
// // .UseInMemoryDatabase("Tests")
// .UseSqlServer(DbConnectionString)
// //.AddInterceptors(new QueryWithNoLockDbCommandInterceptor())
// ;
//});
// 使用内置的扩展注册 DbContextPool 代理服务,只是为了方便使用,只会代理 DbContext
services.AddProxyDbContextPool<TestDbContext>(options =>
{
options
.UseLoggerFactory(loggerFactory)
//.EnableDetailedErrors()
//.EnableSensitiveDataLogging()
// .UseInMemoryDatabase("Tests")
.UseSqlServer(DbConnectionString)
//.AddInterceptors(new QueryWithNoLockDbCommandInterceptor())
;
});
// 注册 AOP 服务
services.AddFluentAspects(options =>
{
// 配置使用 AuditDbContextInterceptor 拦截 DbContext 的 SaveChanges 和 SaveChangesAsync 方法
options.InterceptMethod<DbContext>(m =>
m.Name == nameof(DbContext.SaveChanges)
|| m.Name == nameof(DbContext.SaveChangesAsync))
.With<AuditDbContextInterceptor>()
;
});
// 注册 serviceLocator(可选,根据自己需要
DependencyResolver.SetDependencyResolver(services);
审计配置
AuditConfig.Configure(builder =>
{
builder
// 配置操作用户获取方式
.WithUserIdProvider(EnvironmentAuditUserIdProvider.Instance.Value)
//.WithUnModifiedProperty() // 保存未修改的属性,默认只保存发生修改的属性
// 保存更多属性
.EnrichWithProperty("MachineName", Environment.MachineName)
.EnrichWithProperty(nameof(ApplicationHelper.ApplicationName), ApplicationHelper.ApplicationName)
// 保存到自定义的存储
.WithStore<AuditFileStore>()
.WithStore<AuditFileStore>("logs0.log")
// 忽略指定实体
.IgnoreEntity<AuditRecord>()
// 忽略指定实体的某个属性
.IgnoreProperty<TestEntity>(t => t.CreatedAt)
// 忽略所有属性名称为 CreatedAt 的属性
.IgnoreProperty("CreatedAt")
;
});
使用示例
DependencyResolver.TryInvokeService<TestDbContext>(dbContext =>
{
dbContext.Database.EnsureDeleted();
dbContext.Database.EnsureCreated();
var testEntity = new TestEntity()
{
Extra = new { Name = "Tom" }.ToJson(),
CreatedAt = DateTimeOffset.UtcNow,
};
dbContext.TestEntities.Add(testEntity);
dbContext.SaveChanges();
testEntity.CreatedAt = DateTimeOffset.Now;
testEntity.Extra = new { Name = "Jerry" }.ToJson();
dbContext.SaveChanges();
dbContext.Remove(testEntity);
dbContext.SaveChanges();
var testEntity1 = new TestEntity()
{
Extra = new { Name = "Tom1" }.ToJson(),
CreatedAt = DateTimeOffset.UtcNow,
};
dbContext.TestEntities.Add(testEntity1);
var testEntity2 = new TestEntity()
{
Extra = new { Name = "Tom2" }.ToJson(),
CreatedAt = DateTimeOffset.UtcNow,
};
dbContext.TestEntities.Add(testEntity2);
dbContext.SaveChanges();
});
DependencyResolver.TryInvokeService<TestDbContext>(dbContext =>
{
dbContext.Remove(new TestEntity()
{
Id = 2
});
dbContext.SaveChanges();
});
// disable audit
AuditConfig.DisableAudit();
// enable audit
// AuditConfig.EnableAudit();
审计日志输出结果
More
这样以来就不需要修改原有代码了~~,心情大好,哈哈~
如果应用多有多个 DbContext
有的需要审计,有的不需要审计,则可以在配置的时候指定具体的 DbContext
类型如 TestDbContext
,这样就只会启用 TestDbContext
的自动审计,别的 DbContext
比如 Test2DbContext
就不会自动审计了
Reference
- https://github.com/WeihanLi/WeihanLi.EntityFramework/blob/dev/samples/WeihanLi.EntityFramework.Core3_0Sample/Program.cs
- https://www.nuget.org/packages/WeihanLi.EntityFramework/
- https://www.cnblogs.com/weihanli/p/auto-audit-for-entity-framework.html
打造更好用的 EF 自动审计的更多相关文章
- EF Core 数据变更自动审计设计
EF Core 数据变更自动审计设计 Intro 有的时候我们需要知道每个数据表的变更记录以便做一些数据审计,数据恢复以及数据同步等之类的事情, EF 自带了对象追踪,使得我们可以很方便的做一些审计工 ...
- 端云协同,打造更易用的AI计算平台
内容来源:华为开发者大会2021 HMS Core 6 AI技术论坛,主题演讲<端云协同,HUAWEI HiAI Foundation打造更易用的AI计算平台>. 演讲嘉宾:华为海思AI技 ...
- 打造百度网盘备份利器:自动备份Linux VPS文件和多线程下载百度网盘资源
前一段时间国内的各大网盘百度云盘,金山快盘,360云盘,华为网盘为争夺用户上演空间容量博弈,网盘商们还固执地以为中国的网民都不懂网络技术,可以像某公司那样用一些数字的手段来忽悠用户,参与到网盘商的数字 ...
- EF自动创建数据库步骤之三(自定义数据库初始器)
EF自动创建数据库需要我们告诉数据库如何进行初始化:如创建表后是否需要插入一些基础数据,是否 需要创建存储过程.触发器等.还有就是EF有三种初始化方式(参见下面三个类): DropCreateData ...
- EF自动创建数据库步骤之一(实体类写法)
文章演示使用EF自动创建数据库第一个步骤创建实体类. 一.创建表映射实体类 using System; using System.Collections.Generic; using System.C ...
- C#连接Oracle数据库,通过EF自动生成与数据库表相关的实体类
C#连接Oracle数据库,通过EF自动生成与数据库表相关的实体类 ps:如需转载,请在转载文章明显处,i标注作者和原文地址 一.准备条件 需要自己电脑上已经安装了Oracle数据库,并且已经创建了相 ...
- AI剪辑和自定义UI,打造更智能的剪辑体验
为满足开发者构建高效的应用内视频编辑能力,7月的HMS Core 6.0 推出了视频编辑服务(Video Editor Kit),一站式的视频处理能力获得了积极反响.同时,我们也关注到开发者需要集成丰 ...
- 产品 | GreatSQL,打造更好的MGR生态
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 用 ...
- 全场景AI推理引擎MindSpore Lite, 助力HMS Core视频编辑服务打造更智能的剪辑体验
移动互联网的发展给人们的社交和娱乐方式带来了很大的改变,以vlog.短视频等为代表的新兴文化样态正受到越来越多人的青睐.同时,随着AI智能.美颜修图等功能在图像视频编辑App中的应用,促使视频编辑效率 ...
随机推荐
- Win32程序:与"LPCWSTR"类型的形参不兼容
出现该问题的原因是通常手动输入的字符串都是LPCSTR类型的, 解决办法如下: 在工程处右键,属性-常规-字符集,将Unicode字符集改为为多字节字符集,应用并确认即可. 字符串常量报错: 在常 ...
- wifi无线桥接
考虑到不同路由器配置上或许有细微差别,我此处路由器是水星(牌子)路由器. 首先需要2台路由器,一台已经能够上网,作为主路由器:另一台啥都没有配置,将来用作副路由器,与主路由器桥接. 步骤: 获取主路由 ...
- 分享一下,PHP实现第四方QQ微信扫码登陆,不接入qq互联以及微信开发者平台就可以实现用户对接鹅厂,phpQQ微信扫码登陆
自己抓的QQ包以及整合了网上一些已经封装好了的代码具体如下:QQ: <?php class QQ extends Curl_Api { //获取登录验证码 public function QRc ...
- 浅谈头文件(.h)和源文件(.cpp)的区别
浅谈头文件(.h)和源文件(.cpp)的区别 本人原来在大一写C的时候,都是所有代码写在一个文件里一锅乱煮.经过自己开始写程序之后,发现一个工程只有一定是由多个不同功能.分门别类展开的文件构成的.一锅 ...
- PHP的运行方式(SAPI)
PHP 常量 PHP_SAPI 具有和 php_sapi_name() 相同的值. define('IS_CGI',(0 === strpos(PHP_SAPI,'cgi') || false !== ...
- GoLang——Hello World,打开新世界的大门
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Go语言系列的第一篇文章,我们来聊聊这门新的语言和它的基础语法. 浅谈Golang 作为程序员而言,往往对于学习新的语言都是有抗拒的. ...
- MTK Android Camera新增差值
一. 计算需要的插值 如果原有的插值列表没有我们需要的插值的时候,要通过计算算出符合需求的插值,比如2700W的插值. 具体计算方法如下: 假设像素的长宽分别为X,Y,则插值为XY.由于MTK规定各参 ...
- (js描述的)数据结构[哈希表1.1](8)
(js描述的)数据结构[哈希表1.1](8) 一.数组的缺点 1.数组进行插入操作时,效率比较低. 2.数组基于索引去查找的操作效率非常高,基于内容去查找效率很低. 3.数组进行删除操作,效率也不高. ...
- docker-compose 部分错误
Get https://hub.17kxkx.com/v2/: dial tcp 39.106.209.67:443: connect: connection refused vim /etc/doc ...
- 【学习笔记】Iperf3网络性能测试工具
[学习笔记]Iperf3网络性能测试工具 网络性能评估主要是监测网络带宽的使用率,将网络带宽利用最大化是保证网络性能的基础,但是由于网络设计不合理.网络存在安全漏洞等原因,都会导致网络带宽利用率不高. ...