基于ef core 2.0的数据库增删改审计系统
1.首先是建审计存储表
CREATE TABLE [dbo].[Audit] (
[Id] [uniqueidentifier] NOT NULL,
[EntityName] [nvarchar](100),
[OldValue] [nvarchar](max),
[NewValue] [nvarchar](max),
[StateName] [nvarchar](255),
[CreatedBy] [nvarchar](255),
[CreatedDate] [datetime] NOT NULL,
CONSTRAINT [PK_dbo.Audit] PRIMARY KEY ([Id])
) Go
并建立实体
/// <summary>
/// AuditEntity
/// </summary>
public class AuditEntity : Entity
{
public AuditEntity()
{
this.EntityName = string.Empty;
this.OldValue = string.Empty;
this.NewValue = string.Empty;
this.StateName = string.Empty;
this.CreatedBy = string.Empty;
this.CreatedDate = DateTime.Now;
}
public string EntityName { get; set; }
/// <summary>
///
/// </summary>
public string OldValue { get; set; }
/// <summary>
///
/// </summary>
public string NewValue { get; set; }
/// <summary>
///
/// </summary>
public string StateName { get; set; }
/// <summary>
///
/// </summary>
public string CreatedBy { get; set; }
/// <summary>
///
/// </summary>
public DateTime CreatedDate { get; set; } }
2.EF工作单元类的实现(百度有很多实现方式)
/// <summary>
/// 工作单元接口
/// </summary>
public partial interface IUnitOfWork
{
bool Commit();
}
/// <summary>
/// 工作单元实现类
/// </summary>
public partial class UnitOfWork : IUnitOfWork, IDisposable
{
#region 数据上下文 /// <summary>
/// 数据上下文
/// </summary>
private BaseDbContext _context;
private AuthUserModel _user;
public UnitOfWork(BaseDbContext context, AuthUserModel user)
{
_context = context;
_user = user;
} #endregion
public virtual bool Commit()
{ return _context.SaveChanges() > ;
}
public void Dispose()
{
if (_context != null)
{
_context.Dispose();
}
GC.SuppressFinalize(this);
}
}
这里的AuthUserModel是当前用户类
public class AuthUserModel
{
public string UserName { get; set; }
public string UserId { get; set; }
public string Role { get; set; }
}
3.采用Autofac.Extras.DynamicProxy实现AOP
不知道Autofac.Extras.DynamicProxy能不能直接作用在方法上?
public class AuditLog : IInterceptor
{
private AuthUserModel _user;
private BaseDBContext _context;
public AuditLog(AuthUserModel user, BaseDBContext context )
{
_user = user;
_context = context;
}
public void Intercept(IInvocation invocation)
{
var a = _user;
string name = invocation.Method.Name;
if (name== "Commit")
{
try
{
var list = new List<AuditEntity>();
var b = invocation.InvocationTarget as BaseUnitOfWork;
b.context.ChangeTracker.DetectChanges();
var changes = b.context.ChangeTracker.Entries().Where(x => x.State == EntityState.Added ||
x.State == EntityState.Modified ||
x.State == EntityState.Deleted);
foreach (var change in changes)
{
var temp = new AuditEntity()
{
CreatedBy = _user.UserName
};
//实体名称
temp.EntityName = change.Entity.GetType().Name;
// Entity Added
if (change.State == EntityState.Added)
{
temp.NewValue = JsonConvert.SerializeObject(change.Entity);
temp.StateName = "Added";
list.Add(temp);
}
// Entity Deleted
else if (change.State == EntityState.Deleted)
{
temp.OldValue = JsonConvert.SerializeObject(change.Entity);
temp.StateName = "Deleted";
list.Add(temp);
} // Entity Modified
else if (change.State == EntityState.Modified)
{
//string newStr= "{ " ;
string oldStr = "{ ";
foreach (var propertyEntry in change.Metadata.GetProperties())
{ //if (change.Property(prop.Name).IsModified)
//{
var PropertyName = propertyEntry.Name;
var currentValue = change.Property(propertyEntry.Name).CurrentValue;
var originalValue = change.Property(propertyEntry.Name).OriginalValue;
//newStr = newStr + "\"" + PropertyName + "\"" + ":" + "\"" + currentValue + "\"" + ",";
oldStr = oldStr + "\"" + PropertyName + "\"" + ":" + "\"" + originalValue + "\"" + ",";
//}
}
oldStr = oldStr.Remove(oldStr.Length - , );
oldStr = oldStr + "}";
//newStr = newStr.Remove(oldStr.Length - 1, 1);
//newStr = newStr + "}";
temp.OldValue = oldStr;
temp.NewValue = JsonConvert.SerializeObject(change.Entity);
temp.StateName = "Modified";
list.Add(temp);
}
}
invocation.Proceed();
//将list写入表
//。。。。
}
catch (Exception ex)
{
throw;
}
finally
{ }
}
else
{
invocation.Proceed();
}
}
public IEnumerable<KeyValuePair<string, object>> MapParameters(object[] arguments, ParameterInfo[] getParameters)
{
for (int i = ; i < arguments.Length; i++)
{
yield return new KeyValuePair<string, object>(getParameters[i].Name, arguments[i]);
}
} }
使用AuditLog
builder.RegisterType<AuditLog>();
builder.RegisterType<UnitOfWork>()
.As<IUnitOfWork>().EnableInterfaceInterceptors().InterceptedBy(typeof(AuditLog));
4.调用代码
public class UserManagerApp
{
private IUnitOfWork _uow; public UserManagerApp(
IUnitOfWork uow)
{ _uow = uow;
}
public void Delete(Guid[] ids)
{
//delete 方法
//..........
//提交事务
_uow.Commit();
}
}
[HttpDelete]
[Authorize]
public Response Delete(Guid[] ids)
{
var result = new Response();
try
{
_app.Delete(ids); }
catch (Exception ex)
{ result.Status = false;
result.Message = ex.Message;
}
return result;
}
5.测试


审计日志增加成功
基于ef core 2.0的数据库增删改审计系统的更多相关文章
- EF Core 2.0中如何手动映射数据库的视图为实体
由于Scaffold-DbContext指令目前还不支持自动映射数据库中的视图为实体,所以当我们想使用EF Core来读取数据库视图数据的时候,我们需要手动去做映射,本文介绍如何在EF Core中手动 ...
- 基于EF Core的Code First模式的DotNetCore快速开发框架
前言 最近接了几个小单子,因为是小单子,项目规模都比较小,业务相对来说,也比较简单.所以在选择架构的时候,考虑到效率方面的因素,就采取了asp.net+entity framework中的code f ...
- 基于.net core 2.0+mysql+AceAdmin搭建一套快速开发框架
前言 .net core已经出来一段时间了,相信大家对.net core的概念已经很清楚了,这里就不再赘述.笔者目前也用.net core做过一些项目,并且将以前framework下的一些经验移植到了 ...
- C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入
C# 嵌入dll 在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...
- EF Core中如何设置数据库表自己与自己的多对多关系
本文的代码基于.NET Core 3.0和EF Core 3.0 有时候在数据库设计中,一个表自己会和自己是多对多关系. 在SQL Server数据库中,现在我们有Person表,代表一个人,建表语句 ...
- EF Core 6.0的新计划
今天,我们很兴奋地与你分享Entity Framework Core 6.0的计划. 这个计划汇集了许多人的意见,并概述了我们打算在哪里以及如何优化实体框架(EF Core) 6.0版本.这个计划并不 ...
- .NET 5/.NET Core使用EF Core 5连接MySQL数据库写入/读取数据示例教程
本文首发于<.NET 5/.NET Core使用EF Core 5(Entity Framework Core)连接MySQL数据库写入/读取数据示例教程> 前言 在.NET Core/. ...
- ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First
ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...
- EF Core 2.0 新特性
前言 目前 EF Core 的最新版本为 2.0.0-priview1-final,所以本篇文章主要是针对此版本的一些说明. 注意:如果你要在Visual Studio 中使用 .NET Core 2 ...
随机推荐
- 洛谷【P2024】[NOI2001]食物链
浅谈并查集:https://www.cnblogs.com/AKMer/p/10360090.html 题目传送门:https://www.luogu.org/problemnew/show/P202 ...
- 解决方案: the selected file is a solution file but was created by a newer version of this application and cannot be opened
最近在用IronGithub访问Github api时遇到一个问题: the selected file is a solution file but was created by a newer v ...
- Java基础--注解Annotation
Annotation是给类,方法或域上加的一种特殊的标记,可以通过反射取到注解的类型和值,从而完成某种特定的操作. 定义注解需要使用元注解,元注解有@Retention和@Target //@Rete ...
- Rails上传文件
1.view <%= form_tag({:method =>"post",:controller =>"welcome",:action=& ...
- Python函数(四)-递归函数
递归函数就是函数在自己内部调用自己 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" def Digui(n): print(n ...
- 问题:Oracle 树形遍历;结果:使用oracle进行遍历树操作
使用oracle进行遍历树操作 1:首先数据库中表必须是树形结构的 2:super_department_id 为 department_id 的父节点编号 3:以下语句的执行结果是:depart ...
- jstl 判断 null
<c:if test="${not empty object }"> ${object}不为空 </c:if>
- java之链表
链表是一种物理存储单元上非连续.非顺序的存储结构. 链表是由那几个部分组成的呢? 是由N个节点组成的 每一个节点分为两部分: 1.数据域 ...
- java中用正则表达式判断中文字符串中是否含有英文或者数字
public static boolean includingNUM(String str)throws Exception{ Pattern p = Pattern.compile(" ...
- day17-jdbc 8.ResultSet介绍
但是这些东西在mysql那里有问题.mysql的驱动不是很完善.getClob().getBlob()不好使不是因为程序的问题,而是因为mysql驱动的问题,oracle驱动就没有这个问题,证明ora ...