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. 深入理解http/https之缓存 2

    1:web缓存的实现 web缓存: WEB缓存(cache)位于Web服务器和客户端之间. 缓存会根据请求保存输出内容的副本,例如html页面,图片,文件,当下一个请求来到的时候:如果是相同的URL, ...

  2. virtualvm一次插件安装想到的

    在麒麟操作系统visualvm安装插件失败,因为使用的内网,所以在官网下载了插件到本地:因为本地安装的jdk1.6,为了享受jdk1.8,在visualvm文件中增加了对于jdk1.8的引用: exp ...

  3. VirtualBox-Debian7.2-share

    1.在VirtualBox(用的版本是4.3.6)中,选择虚拟机->设置-> 共享文件夹, 2.添加一个主机上的文件夹readhat用来作为共享文件夹,选中固定分配和自动挂载, 结果:进入 ...

  4. JavaWeb开发Eclipse环境配置--史上最详细的教程

    [前言] JSP本身是JavaWeb中的知识,但是在学习Android网络时,必然要涉及到与服务器之间的交互,所以学一下JSP以及其他JavaWeb的内容还是很有必要的,至少能明白程序在访问服务器时, ...

  5. spring学习十三

    1: RESTful URL : 域和端口 / servlet / 资源 / 参数id 2:  静态资源访问处理? 采用RESTful架构后,需要将web.xml中控制器拦截的请求设置为/,这样会将c ...

  6. appium_python 实现手势密码

    直接上代码吧: from appium.webdriver.common.touch_action import TouchAction from driver import AppiumTest # ...

  7. 2014.12.22 几个有用的oracle正则表达式

    SELECT REGEXP_REPLACE('LSS12345', '[^0-9]') FROM DUAL 结果:12345 '[^0-9]'中的^表示‘非’上述表达式的含义是“将LSS12345中的 ...

  8. leetcode665

    这道题目,主要是判断相邻的两个值的大小,并按照要求的方式,将数组的数值都修正为符合要求的值. 然后通过一次的遍历,计算所累积的移动次数. bool checkPossibility(vector< ...

  9. 封装 Toast

    一. ToastView.java 1 import android.content.Context; import android.view.LayoutInflater; import andro ...

  10. interface 接口 和多态的含义

    <?php //interface关键字用于定义接口 interface ICanEat{ //接口里面的方法不需要方法的实现 public function eat($food) ; } // ...