zoukankan      html  css  js  c++  java
  • 基于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() > 0;
            }
            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 - 1, 1);
                                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 = 0; 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.测试

    审计日志增加成功

  • 相关阅读:
    Unity编译Android的原理解析和apk打包分析
    TokuDB性能测试报告
    一起脱去小程序的外套和内衣
    go单元测试进阶篇
    小程序发布后最全解析!
    部署在腾讯云的公益网站遭受了一次CC攻击
    基于Http原理实现Android的图片上传和表单提交
    腾讯云TCCE培训认证 精彩的第一次
    【腾讯云的1001种玩法】在腾讯云上创建您的SQL Cluster(5)
    腾讯云容器服务的滚动升级使用简介
  • 原文地址:https://www.cnblogs.com/hzzxq/p/7373628.html
Copyright © 2011-2022 走看看