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中的装箱和拆箱

    深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...

  2. 关于C语言字符串函数使用的一点心得

    就字符串的拼接函数为例strcat. 原型:extern char *strcat(char *dest,char *src);用法:#include <string.h> 功能:把src ...

  3. 第一章计算机网络和因特网-day01

    什么是因特网: 其一:构成因特网的基本硬件与软件. 其二:为分布式应用提供服务的联网基础设施. 终端机器称为主机( host ) 或者端系统( end system ) 端系统通过通信链路(commu ...

  4. centos7 安装 mysql-python时 报错 EnvironmentError: mysql_config not found

    pip install mysql-python 然后报错 EnvironmentError: mysql_config not found 网上搜解决方法,需要安装   mysql-devel 然后 ...

  5. 一行删除所有docker container的命令

    ns=`docker | awk '//{print $1}'`;for n in $ns;do docker rm -f $n;done docker | awk '{print $1}'|xarg ...

  6. UCOSII下外部中断的实现

    1.外部中断初始化函数 // EXTI initialize void EXTIX_INIT(void) { EXTI_InitTypeDef EXTI_InitStructure; //定义外部中断 ...

  7. Python:包、模块、类、函数的调用

    一.关系 包一般指文件夹或者安装包(安装包一般也是压缩后的文件夹),里面包含多个.py文件(必须有一个__init__.py文件),一般也含有多个子包(或子文件夹): 一般一个.py文件就是一个模块, ...

  8. Mina APR传输与串口传输讲解---zhengli

    原文地址:Mina Transports(Apache Mina user guide Chapter6 Transport) 1.1.1.APR传输 1.1.1.1.介绍 APR (Apache P ...

  9. 【转】bootstrap模态框(modal)使用remote方法加载数据,只能加载一次的解决办法

    http://blog.csdn.net/coolcaosj/article/details/38369787 bootstrap的modal中,有一个remote选项,可以动态加载页面到modal- ...

  10. 未在本地计算机上注册 Microsoft.ACE.OLEDB.12.0 提供程序

    Visual Studio 8使用了Access数据库,provider选择了ACE.OLEDB,但是运行时出现了错误,提示未在本地计算机上注册"Microsoft.ACE.OLEDB.12 ...