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的数据库增删改审计系统的更多相关文章

  1. EF Core 2.0中如何手动映射数据库的视图为实体

    由于Scaffold-DbContext指令目前还不支持自动映射数据库中的视图为实体,所以当我们想使用EF Core来读取数据库视图数据的时候,我们需要手动去做映射,本文介绍如何在EF Core中手动 ...

  2. 基于EF Core的Code First模式的DotNetCore快速开发框架

    前言 最近接了几个小单子,因为是小单子,项目规模都比较小,业务相对来说,也比较简单.所以在选择架构的时候,考虑到效率方面的因素,就采取了asp.net+entity framework中的code f ...

  3. 基于.net core 2.0+mysql+AceAdmin搭建一套快速开发框架

    前言 .net core已经出来一段时间了,相信大家对.net core的概念已经很清楚了,这里就不再赘述.笔者目前也用.net core做过一些项目,并且将以前framework下的一些经验移植到了 ...

  4. 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,这种形 ...

  5. EF Core中如何设置数据库表自己与自己的多对多关系

    本文的代码基于.NET Core 3.0和EF Core 3.0 有时候在数据库设计中,一个表自己会和自己是多对多关系. 在SQL Server数据库中,现在我们有Person表,代表一个人,建表语句 ...

  6. EF Core 6.0的新计划

    今天,我们很兴奋地与你分享Entity Framework Core 6.0的计划. 这个计划汇集了许多人的意见,并概述了我们打算在哪里以及如何优化实体框架(EF Core) 6.0版本.这个计划并不 ...

  7. .NET 5/.NET Core使用EF Core 5连接MySQL数据库写入/读取数据示例教程

    本文首发于<.NET 5/.NET Core使用EF Core 5(Entity Framework Core)连接MySQL数据库写入/读取数据示例教程> 前言 在.NET Core/. ...

  8. 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 ...

  9. EF Core 2.0 新特性

    前言 目前 EF Core 的最新版本为 2.0.0-priview1-final,所以本篇文章主要是针对此版本的一些说明. 注意:如果你要在Visual Studio 中使用 .NET Core 2 ...

随机推荐

  1. java编程思想第九章接口

    9.1抽象类和抽象方法 为什么要有抽象类? 是希望通过通用接口操作一系列类. 那么抽象类的形式是什么样的呢? 声明类的使用使用abstract关键字,且在该类中应该具有抽象方法. 注:抽象方法被关键字 ...

  2. C# 获取计算机的硬件信息

    /// <summary> /// 获得CPU编号 /// </summary> /// <returns></returns> public stri ...

  3. 静默安装Azure CLI

    Azure的CLI目前已经是基于Python的2.0版本.其信息在下面的链接可以找到: https://github.com/Azure/azure-cli 其安装方法可以根据网站上描述的命令实现: ...

  4. #pragma pack 在BITMAP结构体定义中的使用

    BITMAP位图文件主要分为如下3个部分: 块名称 对应Windows结构体定义 大小(Byte) 文件信息头 BITMAPFILEHEADER 14 位图信息头 BITMAPINFOHEADER 4 ...

  5. 高效C#编码优化

    1.foreach VS for 语句 Foreach 要比for具有更好的执行效率Foreach的平均花费时间只有for的30%.通过测试结果在for和foreach都可以使用的情况下,我们推荐使用 ...

  6. 一张图看懂------left join;right join;inner join

  7. sqlplus 设置显示格式

    使用sqlplus查询显示结果,显示很乱,下面有种方法可以让她显示的更好看些.1.设置显示的宽度:设置前可以先查看当前宽度: SQL> show linesize;linesize 100SQL ...

  8. DAY15-HTTP协议简述

    HTTP协议 一.HTTP协议简介 超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式.协作式和超媒体信息系统的应用层协议.HTTP是万维网 ...

  9. JS中,根据div数值判断弹出窗口

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. sys模块 进度条百分比

    用于提供对Python解释器相关的操作: sys.argv           命令行参数List,第一个元素是程序本身路径 sys.exit(n)        退出程序,正常退出时exit(0) ...