系统操作日志设计-代码实现

本文介绍了一种系统操作日志的设计方案,利用.NET反射技术动态获取实体属性,结合日志设置表实现增删改查等操作的日志记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过思考大概清楚系统操作日志的设计,以下是其UML图:

 

通过上图,我们可以了解知道该UML主要由三个表组成,其中一个主表LogSetting和两个从表分别是LogOperation和LogSettingDetail。

那么怎么样才能通过这样的设计来现实我们的日志功能呢?

其实一开始我就觉得通过.net的反射功能可以很简单、很方便的实现这个功能,所以我就顺着一个思路来实现她;通过反射动态的获取Model实体的属性,然后再根据LogSettingDetail配置来匹配所要记录的字段信息。

 

先来主要的代码吧,发现将思想用文字表达出来还是较困难的,代码比较直接:

代码的实现

using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;  using BLL.Sys;   using System.Collections.Generic; using System.Collections.Specialized; using System.Text; using System.Reflection; /// <summary> /// LogManager 的摘要说明 /// </summary> public class LogManager<T> where T : new()  {     #region Constructor     /// <summary>     /// 日志管理构造函数     /// </summary>     public LogManager()     {         tableName = typeof(T).Name;         Model.Sys.LogSetting model = GetLogSetting(tableName);         if (model != null)         {             businessName = model.BusinessName;             logID = model.LogID;             primaryKey = model.PrimaryKey;             urlTemplate = model.UrlTemplate;             deleteScriptTemplate = model.DeleteScriptTemplate;             updateScriptTemplate = model.UpdateScriptTemplate;         }         else         {             throw new ArgumentNullException("日志设置为空!");         }     }     /// <summary>    ///      /// 日志管理构造函数     /// </summary>     /// </summary>     /// <param name="tableName">表名</param>     /// <param name="businessName">业务名称</param>     public LogManager(string tableName, string businessName)     {         this.tableName = tableName;         this.businessName = businessName;          Model.Sys.LogSetting model = GetLogSetting(tableName, businessName);         if (model != null)         {             logID = model.LogID;             primaryKey = model.PrimaryKey;             urlTemplate = model.UrlTemplate;             deleteScriptTemplate = model.DeleteScriptTemplate;             updateScriptTemplate = model.UpdateScriptTemplate;         }         else         {             throw new ArgumentNullException("日志设置为空!");         }     }     #endregion       #region Properties     private int logID;     private string tableName;     private string businessName;     private string primaryKey;     private string urlTemplate;     private string deleteScriptTemplate;     private string updateScriptTemplate;       /// <summary>     /// 日志设置实体列表     /// </summary>     public List<Model.Sys.LogSetting> LogSettingList     {         get         {             System.Web.Caching.Cache cache = HttpRuntime.Cache;             List<Model.Sys.LogSetting> list = cache["LogSettingList"] as List<Model.Sys.LogSetting>;             if (list != null && list.Count > 0)             {                 return list;             }             else             {                 LogSetting bll = new LogSetting();                 list = bll.GetModelList(string.Empty);                 cache["LogSettingList"] = list;                 return list;             }         }         set         {             System.Web.Caching.Cache cache = HttpRuntime.Cache;             cache["LogSettingList"] = null;         }     }     /// <summary>     /// 日志设置明细     /// </summary>     public List<Model.Sys.LogSettingDetail> LogSettingDetail     {         get         {             System.Web.Caching.Cache cache = HttpRuntime.Cache;             List<Model.Sys.LogSettingDetail> list = cache["LogSettingDetail"] as List<Model.Sys.LogSettingDetail>;             if (list != null && list.Count > 0)             {                 return list;             }             else             {                 LogSettingDetail bll = new LogSettingDetail();                 list = bll.GetModelList(string.Empty);                 cache["LogSettingDetail"] = list;                 return list;             }         }         set         {             System.Web.Caching.Cache cache = HttpRuntime.Cache;             cache["LogSettingDetail"] = null;         }     }      #endregion      #region Method     /// <summary>     /// 通过logId获取日志设置明细     /// </summary>     /// <param name="logId">日志设置编号</param>     /// <returns></returns>     private List<Model.Sys.LogSettingDetail> GetLogSettingDetails(int logId)     {         if (logId == 0)             throw new ArgumentNullException("LogID为空");          List<Model.Sys.LogSettingDetail> list = new List<Model.Sys.LogSettingDetail>();         foreach (Model.Sys.LogSettingDetail var in LogSettingDetail)         {             if (var.LogID == logId)                 list.Add(var);         }         return list;     }     /// <summary>     /// 通过tableName和businessName来获取日志设置对象     /// </summary>     /// <param name="tableName"></param>     /// <param name="businessName"></param>     /// <returns></returns>     private Model.Sys.LogSetting GetLogSetting(string tableName, string businessName)     {         foreach (Model.Sys.LogSetting var in LogSettingList)         {             if (var.TableName.Equals(tableName, StringComparison.InvariantCultureIgnoreCase) && var.BusinessName.Equals(businessName, StringComparison.InvariantCultureIgnoreCase))                 return var;         }         return null;     }     private Model.Sys.LogSetting GetLogSetting(string tableName)     {         foreach (Model.Sys.LogSetting var in LogSettingList)         {             if (var.TableName.Equals(tableName, StringComparison.InvariantCultureIgnoreCase))                 return var;         }         return null;     }       /// <summary>     /// 比较两个实体,然后返回实体中每个属性值不同的内容     /// </summary>     /// <param name="oldObj"></param>     /// <param name="newObj"></param>     /// <returns></returns>     public string Compare(T oldObj, T newObj)     {         Type objTye = typeof(T);          StringBuilder sbResult = new StringBuilder();         string tableHeader = "<table class=\"GridView\" cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"gv\" style=\"border-collapse:collapse;\">";         tableHeader += "<tr><th scope=\"col\">序号</th><th scope=\"col\">字段</th><th scope=\"col\">名称</th><th scope=\"col\">旧值</th><th scope=\"col\">新值</th></tr>";          string tableRow = "<tr class='{0}'><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td></tr>";          List<Model.Sys.LogSettingDetail> list = GetLogSettingDetails(logID);         int i = 1;          foreach (Model.Sys.LogSettingDetail var in list)         {             PropertyInfo property = objTye.GetProperty(var.ColumnName);             if (property != null && !property.IsSpecialName)             {                 object o = property.GetValue(oldObj, null);                 object n = property.GetValue(newObj, null);                 if (!IsEqual(property.PropertyType, o, n))                 {                     sbResult.AppendFormat(tableRow, i % 2 == 0 ? "odd" : "even", i, var.ColumnName, var.ColumnText, o, n);                     i++;                 }              }         }          sbResult.Append("</table>");          #region Add Log Record          if (i > 1)         {             Model.Sys.LogOperation operModel = new Model.Sys.LogOperation();             operModel.LogID = logID;             operModel.OperationType = (int)OperationType.Update;             operModel.Content = tableHeader + sbResult.ToString();             operModel.CreateTime = DateTime.Now;                                       if (HttpContext.Current != null)                 operModel.CreateUser = HttpContext.Current.User.Identity.Name;             if (!string.IsNullOrEmpty(primaryKey))             {                 PropertyInfo p = objTye.GetProperty(primaryKey);                 object o = p.GetValue(newObj, null);                 if (o != null)                 {                     operModel.PrimaryKeyValue = o.ToString();                      if (urlTemplate.Contains("{0}"))                         operModel.Url = string.Format(urlTemplate, o.ToString());                 }              }             LogOperation operBll = new LogOperation();             operBll.Add(operModel);          }         #endregion          return tableHeader + sbResult.ToString();      }     /// <summary>     /// 删除实体操作,这里并不是真的删除该实体,而是将删除的操作记录在日志中     /// </summary>     /// <param name="obj"></param>     /// <returns></returns>     public string Delete(T obj)     {         Type objTye = typeof(T);           StringBuilder sbResult = new StringBuilder();         string tableHeader = "<table class=\"GridView\" cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"gv\" style=\"border-collapse:collapse;\">";         tableHeader += "<tr><th scope=\"col\">序号</th><th scope=\"col\">字段</th><th scope=\"col\">名称</th><th scope=\"col\">值</th></tr>";          string tableRow = "<tr class='{0}'><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td></tr>";          List<Model.Sys.LogSettingDetail> list = GetLogSettingDetails(logID);         int i = 1;         foreach (Model.Sys.LogSettingDetail var in list)         {             PropertyInfo property = objTye.GetProperty(var.ColumnName);             if (property != null && !property.IsSpecialName)             {                 object o = property.GetValue(obj, null);                  sbResult.AppendFormat(tableRow, i % 2 == 0 ? "odd" : "even", i, var.ColumnName, var.ColumnText, o);                 i++;             }         }          sbResult.Append("</table>");           #region Add Log Record                 Model.Sys.LogOperation operModel = new Model.Sys.LogOperation();         operModel.LogID = logID;         operModel.OperationType = (int)OperationType.Delete;         operModel.Content = tableHeader + sbResult.ToString();         operModel.CreateTime = DateTime.Now;         if (!string.IsNullOrEmpty(primaryKey))         {             PropertyInfo p = objTye.GetProperty(primaryKey);             object o = p.GetValue(obj, null);             if (o != null)             {                 operModel.PrimaryKeyValue = o.ToString();                 if (urlTemplate.Contains("{0}"))                     operModel.Url = string.Format(urlTemplate, o.ToString());             }         }         if (HttpContext.Current != null)             operModel.CreateUser = HttpContext.Current.User.Identity.Name;         LogOperation operBll = new LogOperation();         operBll.Add(operModel);          #endregion         return string.Empty;     }     /// <summary>     /// 添加实体,将添加的操作记录在日志中     /// </summary>     /// <param name="obj"></param>     /// <returns></returns>     public string Add(T obj)     {         Type objTye = typeof(T);           StringBuilder sbResult = new StringBuilder();         string tableHeader = "<table class=\"GridView\" cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"gv\" style=\"border-collapse:collapse;\">";         tableHeader += "<tr><th scope=\"col\">序号</th><th scope=\"col\">字段</th><th scope=\"col\">名称</th><th scope=\"col\">值</th></tr>";          string tableRow = "<tr class='{0}'><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td></tr>";          List<Model.Sys.LogSettingDetail> list = GetLogSettingDetails(logID);         int i = 1;         foreach (Model.Sys.LogSettingDetail var in list)         {             PropertyInfo property = objTye.GetProperty(var.ColumnName);             if (property != null && !property.IsSpecialName)             {                 object o = property.GetValue(obj, null);                  sbResult.AppendFormat(tableRow, i % 2 == 0 ? "odd" : "even", i, var.ColumnName, var.ColumnText, o);                 i++;             }         }          sbResult.Append("</table>");           #region Add Log Record                Model.Sys.LogOperation operModel = new Model.Sys.LogOperation();         operModel.LogID = logID;         operModel.OperationType = (int)OperationType.Add;         operModel.Content = tableHeader + sbResult.ToString();         operModel.CreateTime = DateTime.Now;         if (!string.IsNullOrEmpty(primaryKey))         {             PropertyInfo p = objTye.GetProperty(primaryKey);             object o = p.GetValue(obj, null);             if (o != null)             {                 operModel.PrimaryKeyValue = o.ToString();                 if (urlTemplate.Contains("{0}"))                     operModel.Url = string.Format(urlTemplate, o.ToString());             }         }         if (HttpContext.Current != null)             operModel.CreateUser = HttpContext.Current.User.Identity.Name;         LogOperation operBll = new LogOperation();         operBll.Add(operModel);          #endregion         return string.Empty;     }     /// <summary>     /// 复制一个对象     /// </summary>     /// <param name="obj"></param>     /// <returns></returns>     public T Clone(T obj)     {         Type objTye = typeof(T);         T model = new T();                  PropertyInfo[] properties = objTye.GetProperties();         foreach (PropertyInfo property in properties)         {             if(!property.IsSpecialName)             {                 object o = property.GetValue(obj, null);                 property.SetValue(model, o, null);             }                       }         return model;     }      private bool IsEqual(Type dataType, object oldObj, object newObj)     {         if (oldObj == null && newObj == null)             return true;          if (dataType == typeof(int))         {             return (int)oldObj == (int)newObj;         }         else if (dataType == typeof(decimal))         {             return (decimal)oldObj == (decimal)newObj;         }         else if (dataType == typeof(double))         {             return (double)oldObj == (double)newObj;         }         else if (dataType == typeof(Guid))         {             return (Guid)oldObj == (Guid)newObj;         }         else if (dataType == typeof(DateTime))         {             return (DateTime)oldObj == (DateTime)newObj;         }         else             return oldObj.Equals(newObj);      }      #region Script Excute      //public int DeleteBusRecode(string primaryKeyValue)     //{     //    if (string.IsNullOrEmpty(tableName))     //        throw new ArgumentException("tableName为空");     //    if(string.IsNullOrEmpty(primaryKey))     //        throw new ArgumentException("primaryKey为空");     //    if (string.IsNullOrEmpty(deleteScriptTemplate))     //        throw new ArgumentException("deleteScriptTemplate为空");      //    string strSql = string.Format(deleteScriptTemplate, primaryKeyValue);      //    Database db = DatabaseFactory.CreateDatabase();     //    return 0;               //}     #endregion      #endregion   } public enum OperationType {     Select = 0,     Add = 1,     Update = 2,     Delete = 3 }

 

使用的场景

Model文件:

public class EmployeeModel  {  public int ID{get;set;}  public string Name{get;set;}  …  } 
下面介绍如何将系统操作日志集成到你的业务系统中
添加操作:
EmployeeBll bll = new EmployeeBll();
EmployeeModel model = new EmployeeModel();
/* model 实体经过漫长的 赋值 后… */
bll.Add(model);    //添加实体
//添加系统操作记录
//日志 LogManager<EmployeeModel> log = new LogManager<EmployeeModel>();
log.Add(model);
 
更新操作:
EmployeeBll bll = new EmployeeBll();
EmployeeModel model = bll.GetModel(employeeID);
LogManager<EmployeeModel> log = new LogManager<EmployeeModel>();
EmployeeModel modelOld = log.Clone(model);   //克隆EmployeeModel实体对象,这个主要是在系统操作日志记录时使用的
 
/* model 实体又经过漫长的 赋值 后… */
bll.Update(model);     //更新实体
//将更新的内容写入系统操作日志中
log.Compare(modelOld, model);    //原来的实体和赋值后的实体对比,并将更新的内容写入系统操作日志中
 
删除操作:
在GridView的RowDeleting事件中获取要删除的实体
EmployeeBll bll = new EmployeeBll();
EmployeeModel model = bll.GetModel(employeeID);
bll.Delete(employeeID);
LogManager<EmployeeModel> log = new LogManager<EmployeeModel>(); log.Delete(model);       //实体的内容记录到日志中
 

 

总结:

大家可以看到代码还是比较粗糙的,有不少的重复的代码,下一节将会讨论如何进行系统操作日志管理

另外如何大家有什么意见或想法请分享提出。

 

本节用到的知识点

1、泛型

2、反射

3、缓存

 

优点:

1、使用和集成方便,代码量小;

2、大大提高工作效率,避免表爆炸;

 

缺点:

1、代码有待优化;

2、可扩展性较差

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值