第一篇 Entity Framework Plus 之 Audit
一般系统会有登陆日志,操作日志,异常日志,已经满足大部分的需求了。但是有时候,还是需要Audit 审计日志,审计日志,主要针对数据增,改,删操作数据变化的记录,主要是对数据变化的一个追踪过程。其中主要追踪数据关键点如下
1. 新增 具体新增哪些数据,值是什么,新增人谁。
2. 修改 具体修改哪些数据,之前值是什么,修改后值是什么,修改人谁。
3. 删除 具体删除哪些数据,之前值是什么,删除人谁。
有了这个Audit追踪过程,当那天,用户操作的数据出现问题,你就可以根据这个Audit将数据恢复到某个状态,当然这个Audit,也不仅仅数据出问题才有用,在分析数据时,也有用。
这几年都在做基于ASP.NET MVC & Entity Framework 搭建企业技术框架,很早之前就想自己写一个Audit机制,想着把数据变化保存为json,由于之前公司很多事情所有也没有静下心来想怎么在现有架构上加这块的事情。这几天自己也在找工作(深圳找工作,如果大家的公司缺一个架构的岗位,我可以客串一下,13926537904,不胜感激),所有不忙了,就再次想起Audit来。就开始倒腾起来。
ZZZ Project 这家外国公司,有很多关于.NET和数据访问的项目,有收费的,有开源的,我之前介绍过 Z.ExtensionMethods 一个强大的开源扩展库 就出自该名下,其他有 如下
1. Bulk-Operations ,这个我相信大家也不陌生,Ado.Net 批量操作数据组件 收费
2. EntityFramework-Extensions ,这个Entity Framework 扩展库,这个是EntityFramework 批量操作数据扩展组件 收费
3. EntityFramework-Plus 这个是最近才发布的 Entity Framework + 库,比EntityFramework-Extensions 新增更多的功能。开源免费
4. Dapper-Plus 这个是最近才发布的 Drpper + 库
5. Eval-SQL.NET 关于SQL的,没有使用过,暂时不详细说。
6. Eval-Expression.NET 关于表达式的,没有使用过,暂时不详细说。
等等,还一些我就不一一介绍了,大家可以在下面网站,细看自己感兴趣的。
zzz projects GitHub: https://github.com/zzzprojects
我要说的Audit,在 EntityFramework-Plus 库里面,他有提供,等一下我会实作一下给大家看一下,这个库所提供的功能,如下
- Batch Operations
- Batch Delete
- Batch Update
- LINQ
- LINQ Dynamic
- Query
- Query Cache
- Query Deferred
- Query Filter
- Query Future
- Query IncludeFilter
- Query IncludeOptimized
- Audit
如果购买了 EntityFramework-Extensions 这个扩展库,EntityFramework-Extensions 这个库的功能也会包含在里面。
EntityFramework-Plus GitHub 主页 : http://entityframework-plus.net/
EntityFramework-Plus GitHub 源代码: https://github.com/zzzprojects/EntityFramework-Plus
说了一大堆废话,没有入正题,不好意思,开始真正实作 EntityFramework-Plus 之 Audit 部分。
一. 创建解决方案,以及新增基础设施项目(DbContext,Models,Mapping,Demo),这里就不再介绍了,大家参考 Entity Framework 6 开发系列 目录 实作一下即可,就只贴一些关键代码以及项目截图(还未引用EntityFramework-Plus)。
1. 解决方案截图
EntityFrameworkPlus.Demo 项目:控制台程序,应用层 Demo。
EntityFrameworkPlus.DbContext 项目 :DbContext
EntityFrameworkPlus.Mappings 项目:映射模型
EntityFrameworkPlus.Models 项目:模型
2. 关键代码 (还是以订单为义务)
OrderModel
using System;namespace EntityFrameworkPlus.Models {public class OrderModel{public Guid OrderGuid { get; set; }public string OrderNo { get; set; }public string OrderCreator { get; set; }public DateTime OrderDateTime { get; set; }public string OrderStatus { get; set; }public string Description { get; set; }public string Creator { get; set; }public DateTime CreateDateTime { get; set; }public string LastModifier { get; set; }public DateTime? LastModifiedDateTime { get; set; } } }
OrderMapp
using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity.ModelConfiguration; using EntityFrameworkPlus.Models;namespace EntityFrameworkPlus.Mappings {public class OrderMap : EntityTypeConfiguration<OrderModel>{public OrderMap(){this.HasKey(m => m.OrderGuid);this.Property(m => m.OrderGuid).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);this.Property(m => m.OrderNo).IsRequired().HasMaxLength(30);this.Property(m => m.OrderCreator).IsRequired().HasMaxLength(20);this.Property(m => m.OrderStatus).IsRequired().HasMaxLength(30);this.Property(m => m.Description).HasMaxLength(1000);this.Property(m => m.Creator).IsRequired().HasMaxLength(20);this.Property(m => m.LastModifier).HasMaxLength(15).HasMaxLength(20);this.ToTable("Sample_Order");this.Property(m => m.OrderGuid).HasColumnName("OrderGuid");this.Property(m => m.OrderNo).HasColumnName("OrderNo");this.Property(m => m.OrderCreator).HasColumnName("OrderCreator");this.Property(m => m.OrderDateTime).HasColumnName("OrderDateTime");this.Property(m => m.OrderStatus).HasColumnName("OrderStatus");this.Property(m => m.Description).HasColumnName("Description");this.Property(m => m.Creator).HasColumnName("Creator");this.Property(m => m.CreateDateTime).HasColumnName("CreateDateTime");this.Property(m => m.LastModifier).HasColumnName("LastModifier");this.Property(m => m.LastModifiedDateTime).HasColumnName("LastModifiedDateTime");}} }
EntityFrameworkPlusDbContext
using System.Data.Entity; using EntityFrameworkPlus.Mappings; using EntityFrameworkPlus.Models;namespace EntityFrameworkPlus.DbContext {public class EntityFrameworkPlusDbContext : System.Data.Entity.DbContext{public EntityFrameworkPlusDbContext(): base("EntityFrameworkPlusConnection"){}public DbSet<OrderModel> Orders { get; set; }protected override void OnModelCreating(DbModelBuilder modelBuilder){modelBuilder.Configurations.Add(new OrderMap());base.OnModelCreating(modelBuilder);}} }
Program
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using EntityFrameworkPlus.DbContext; using EntityFrameworkPlus.Models;namespace EntityFrameworkPlus.Demo {class Program{static void Main(string[] args){AddOrder();}public static void AddOrder(){using (var dbContext = new EntityFrameworkPlusDbContext()){dbContext.Orders.Add(new OrderModel{OrderNo = "ORDER0001",OrderCreator = "david",OrderDateTime = DateTime.Now,OrderStatus = "已出库",Creator = "david",CreateDateTime = DateTime.Now});dbContext.SaveChanges();}}} }
3. 项目与项目引用关系(代码图)
二. EntityFramework-Plus 使用
1. 在EntityFrameworkPlus.DbContext,EntityFrameworkPlus.Demo 两个项目中安装 EntityFramework-Plus 库,右键项目 选择“管理NuGet程序包”,联机中,搜索“Z.EntityFramework.Plus”(搜到很多个EntityFramework.Plus 开头组件,大家不要被吓到了,zzz projects 将 Z.EntityFramework.Plus 组件,按照EntityFramework版本分,然后再按照 Z.EntityFramework.Plus 功能来分,比较独立,所以会有这么多个组件,我们这里用的是Entity Framework 6 ,要用到Audit功能),选择 “EntityFramework.Plus (EF6) Audit” 进行安装。
2. EntityFramework.Plus Audit 把数据追踪记录,分成两个表记录
AuditEntries 表 ,记录实体 名称,所属上一级命名空间,状态(增,改,删),状态名称,创建人。
AuditEntryProperties 表,具体数据字段信息,字段名称,关系名称,记录旧,新值。
将 EntityFramework.Plus 提供创建两个表的SQL语句,在自己的数据库里面执行。我的数据库“EntityFrameworkSample”,执行完了,总共就有三个“AuditEntries”,“AuditEntryProperties ”,“Sample_Order”。下面是创建 Audit 相关表SQL,以及数据库结构截图。
CREATE TABLE [dbo].[AuditEntries] ([AuditEntryID] [int] NOT NULL IDENTITY,[EntitySetName] [nvarchar](255),[EntityTypeName] [nvarchar](255),[State] [int] NOT NULL,[StateName] [nvarchar](255),[CreatedBy] [nvarchar](255),[CreatedDate] [datetime] NOT NULL,CONSTRAINT [PK_dbo.AuditEntries] PRIMARY KEY ([AuditEntryID]) )GOCREATE TABLE [dbo].[AuditEntryProperties] ([AuditEntryPropertyID] [int] NOT NULL IDENTITY,[AuditEntryID] [int] NOT NULL,[RelationName] [nvarchar](255),[PropertyName] [nvarchar](255),[OldValue] [nvarchar](max),[NewValue] [nvarchar](max),CONSTRAINT [PK_dbo.AuditEntryProperties] PRIMARY KEY ([AuditEntryPropertyID]) )GOCREATE INDEX [IX_AuditEntryID] ON [dbo].[AuditEntryProperties]([AuditEntryID])GOALTER TABLE [dbo].[AuditEntryProperties] ADD CONSTRAINT [FK_dbo.AuditEntryProperties_dbo.AuditEntries_AuditEntryID] FOREIGN KEY ([AuditEntryID]) REFERENCES [dbo].[AuditEntries] ([AuditEntryID]) ON DELETE CASCADEGO
3. 在 “EntityFrameworkPlus.DbContext” 项目的“EntityFrameworkPlusDbContext” ,配置Audit 两个表实体集合。配置完成代码如下。
using System.Data.Entity; using EntityFrameworkPlus.Mappings; using EntityFrameworkPlus.Models; using Z.EntityFramework.Plus;namespace EntityFrameworkPlus.DbContext {public class EntityFrameworkPlusDbContext : System.Data.Entity.DbContext{public EntityFrameworkPlusDbContext(): base("EntityFrameworkPlusConnection"){}public DbSet<AuditEntry> AuditEntries { get; set; }public DbSet<AuditEntryProperty> AuditEntryProperties { get; set; }public DbSet<OrderModel> Orders { get; set; }protected override void OnModelCreating(DbModelBuilder modelBuilder){modelBuilder.Configurations.Add(new OrderMap());base.OnModelCreating(modelBuilder);}} }
4. 在“EntityFrameworkPlus.Demo” Program 调整代码,使用EntityFramework.Plus Audit 代码,以及增加及调整了 对Sample_Order 增,改,删数据操作。调整代码如下。
using System; using System.Data.Entity; using System.Linq; using EntityFrameworkPlus.DbContext; using EntityFrameworkPlus.Models; using Z.EntityFramework.Plus;namespace EntityFrameworkPlus.Demo {class Program{static void Main(string[] args){AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) =>{var customAuditEntries = audit.Entries.Select(x => Import(x));(context as EntityFrameworkPlusDbContext).AuditEntries.AddRange(customAuditEntries);};AddOrder();}public static void AddOrder(){using (var dbContext = new EntityFrameworkPlusDbContext()){var audit = new Audit { CreatedBy = "david" };dbContext.Orders.Add(new OrderModel{OrderNo = "ORDER0001",OrderCreator = "david",OrderDateTime = DateTime.Now,OrderStatus = "已出库",Creator = "david",CreateDateTime = DateTime.Now});dbContext.SaveChanges(audit);}}public static void UpdateOrder(){using (var dbContext = new EntityFrameworkPlusDbContext()){var audit = new Audit { CreatedBy = "david" };var orderAsync = dbContext.Orders.FirstAsync();var order = orderAsync.Result;order.LastModifier = "davidzhou";order.LastModifiedDateTime = DateTime.Now;order.OrderStatus = "已完成";dbContext.Entry(order);dbContext.SaveChanges(audit);}}public static void DeleteOrder(){using (var dbContext = new EntityFrameworkPlusDbContext()){var audit = new Audit { CreatedBy = "david" };var orderAsync = dbContext.Orders.FirstAsync();var order = orderAsync.Result;dbContext.Entry(order).State = EntityState.Deleted;dbContext.SaveChanges(audit);}}public static AuditEntry Import(AuditEntry entry){var customAuditEntry = new AuditEntry{EntitySetName = entry.EntitySetName,EntityTypeName = entry.EntityTypeName,State = entry.State,StateName = entry.StateName,CreatedBy = entry.CreatedBy,CreatedDate = entry.CreatedDate};customAuditEntry.Properties = entry.Properties.Select(x => Import(x)).ToList();return customAuditEntry;}public static AuditEntryProperty Import(AuditEntryProperty property){var customAuditEntry = new AuditEntryProperty{RelationName = property.RelationName,PropertyName = property.PropertyName,OldValue = property.OldValueFormatted,NewValue = property.NewValueFormatted};return customAuditEntry;}} }
5. 对 Sample_Order 表,做新增 操作,三张表变化如图,我这边就不解释了,大家应该多看得懂。
5. 对 Sample_Order 表,做修改 操作,三张表变化如图,我这边就不解释了,大家应该多看得懂。
5. 对 Sample_Order 表,做删除 操作,三张表变化如图,我这边就不解释了,大家应该多看得懂。
好了,到此博文,已经结束,这里要说明的,Entity Framework Plus Audit 部分,我只使用到一些,还要其他大家可以自行,GitHub 更加深入的了解。
此篇博文的源代码: https://github.com/haibozhou1011/EntityFramework-PlusSample
转载于:https://www.cnblogs.com/davidzhou/p/5376542.html
第一篇 Entity Framework Plus 之 Audit相关推荐
- 第四篇 Entity Framework Plus 之 Batch Operations
用 Entity Framework 进行 增,删,改.都是基于Model进行的,且Model都是有状态追踪的.这样Entity Framework才能正常增,删,改. 有时候,要根据某个字段,批量 ...
- 第三篇 Entity Framework Plus 之 Query Cache
离上一篇博客,快一周,工作太忙,只能利用休息日来写一些跟大家分享,Entity Framework Plus 组件系列文章,之前已经写过两篇 第一篇 Entity Framework Plus 之 A ...
- 第二篇 Entity Framework Plus 之 Query Future
从性能的角度出发,能够减少 增,删,改,查,跟数据库打交道次数,肯定是对性能会有所提升的(这里单纯是数据库部分). 今天主要怎样减少Entity Framework查询跟数据库打交道的次数,来提高查询 ...
- 第一篇:Entity Framework 简介
先从ORM说起吧,很多年前,由于.NET的开源组件不像现在这样发达,更别说一个开源的ORM框架,出于项目需要,以及当时OOP兴起(总不至于,在项目里面全是SQL语句),就自己开始写ORM框架.要开发O ...
- Entity Framework快速入门笔记第四篇—ModelFirst
前言:在上一篇博客中我们做了一个小的Demo,使用EF实现了对数据库的增删改查的操作,所谓学习,我们就要学会举一反三,所以好好学习一下上一篇的内容还是方便以后的扩展学习,这篇博客我们主要来研究一下Mo ...
- oracle精简版_使用Entity Framework Core访问数据库(Oracle篇)
前言 哇..看看时间 真的很久很久没写博客了 将近一年了. 最近一直在忙各种家中事务和公司的新框架 终于抽出时间来更新一波了. 本篇主要讲一下关于Entity Framework Core访问ora ...
- 使用Entity Framework Core访问数据库(DB2篇)
上一篇讲了一些EF Core访问Oracle的坑.(感兴趣请移步:使用Entity Framework Core访问数据库(Oracle篇)) 这篇主要讲一下关于EF Core访问DB2的一揽子~问题 ...
- 使用Entity Framework Core访问数据库(Oracle篇)
前言 哇..看看时间 真的很久很久没写博客了 将近一年了. 最近一直在忙各种家中事务和公司的新框架 终于抽出时间来更新一波了. 本篇主要讲一下关于Entity Framework Core访问ora ...
- 使用 ASP.NET Core, Entity Framework Core 和 ABP 创建N层Web应用 第二篇
介绍 这是"使用 ASP.NET Core ,Entity Framework Core 和 ASP.NET Boilerplate 创建N层 Web 应用"系列文章的第二篇.以下 ...
最新文章
- 关于mybatis中基本类型条件判断问题
- vue-cli安装、node-sass安装、mintUI组件库安装
- Google Analytics虚拟页面和事件追踪的区别
- k8s控制器:Job和CronJob
- python3 面向对象_Python3 面向对象
- 这里有个古老的车站:三年只为一人开
- quick time不可用_那些校园中“不可言说”的鄙视链
- 机器学习、深度学习方面书籍收集(持续更新……)
- C++socket编程(六):6.1 设置socket的阻塞和非阻塞
- 案例篇-HBase 实战之 MOB 使用指南
- 眉山市谷歌高清卫星地图下载
- webshell及木马详解
- 用Excel制作二维码
- 计算机word排版实训报告,Word排版实训报告
- 麒麟V10图形界面安装与运行人大金仓数据库
- 如何设置Ubuntu键盘输入法框架为fcitx
- Halcon生成标定描述文件
- PS如何精确设置参考线,标尺,辅助线
- BigDecimal取余运算
- 【华人学者风采】汪萌 合肥工业大学
热门文章
- 模块降额设计_模块电源需要注意的四个点
- 横流式冷却塔计算风量_冷却塔空气动力是怎么计算的?
- java多线程并发控制_Java多线程与并发控制
- 二叉树的最小深度Python解法
- python databaselibrary_Robot Framework下DataBaseLibrary的使用
- linux+路由器信号检测工具,Linux下常用网络故障调试工具介绍之Ping命令使用
- java mvc增删改查_springmvc-CRUC增删改查
- 消除左递归c++代码_「leetcode」129. 求根到叶子节点数字之和【递归中隐藏着回溯】详解...
- colinux php,利用colinux 搭建linux开发环境
- mysql order by sql注入_mybatis中#{}和${}的区别及order by的sql注入问题