/// <summary> /// Определяет был ли изменен объект /// </summary> /// <param name="obj"></param> /// <returns></returns> public bool f_IsChanged(I_ELog obj) { bool isChanged = false; Cl_ELogClassAttribute classAtr = Cl_EntityLog.f_GetClassAttribute <Cl_ELogClassAttribute>(obj); if (classAtr == null) { return(true); } if (this.entityLogType != classAtr.p_EntityType) { return(true); } Dictionary <PropertyInfo, object> currentValues = f_GetValues(obj); foreach (KeyValuePair <PropertyInfo, object> item in currentValues) { if (!lastValues.ContainsKey(item.Key)) { continue; } if (Cl_EntityCompare.f_IsCompare(item.Key.PropertyType, lastValues[item.Key], item.Value) == false) { isChanged = true; break; } } return(isChanged); }
/// <summary> /// Записывает индивидуальное сообщение лога для переданного объекта /// </summary> /// <param name="obj">Объект логирования</param> /// <param name="message">Сообщение лога</param> public static void f_CustomMessageLog(I_ELog obj, string message) { if (Cl_App.m_DataContext == null) { return; } Cl_ELogClassAttribute classAtr = Cl_EntityLog.f_GetClassAttribute <Cl_ELogClassAttribute>(obj); if (classAtr == null) { return; } Cl_Log outEvent = new Cl_Log { p_SessionID = Cl_SessionFacade.f_GetInstance().p_SessionID, p_ElementID = obj.p_GetLogEntityID, p_Version = obj.p_Version, p_EntityType = classAtr.p_EntityType, p_ChangeTime = DateTime.Now, p_Event = message, p_UserName = Cl_SessionFacade.f_GetInstance().p_Doctor.p_FIO }; Cl_App.m_DataContext.p_Logs.Add(outEvent); Cl_App.m_DataContext.SaveChanges(); }
/// <summary> /// Возвращает сформированный объект сообщения лога для текущего объекта /// </summary> private Cl_Log f_CreateEvent(I_ELog obj, string message) { Cl_Log outEvent = new Cl_Log { p_SessionID = Cl_SessionFacade.f_GetInstance().p_SessionID, p_ElementID = obj.p_GetLogEntityID, p_Version = obj.p_Version, p_EntityType = this.entityLogType, p_ChangeTime = DateTime.Now, p_Event = message, p_UserName = Cl_SessionFacade.f_GetInstance().p_Doctor.p_FIO }; return(outEvent); }
/// <summary>Сохранение изменений БД с логированием изменений</summary> /// <param name="obj"></param> public void f_SaveChanges(Cl_EntityLog a_Log, I_ELog a_Obj) { using (var transaction = Database.BeginTransaction()) { try { SaveChanges(); a_Log.f_SaveEntity(a_Obj); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); MonitoringStub.Error("Error_Tree", "Не удалось сохранить изменения в базе данных", ex, null, null); } } }
/// <summary> /// Возвращает список логируемых свойств объекта /// </summary> private Dictionary <PropertyInfo, object> f_GetValues(I_ELog obj) { Dictionary <PropertyInfo, object> values = new Dictionary <PropertyInfo, object>(); Type type = obj.GetType(); foreach (PropertyInfo mInfo in type.GetProperties()) { foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo)) { if (attr.GetType() == typeof(Cl_ELogPropertyAttribute)) { values.Add(mInfo, mInfo.GetValue(obj, null)); } } } return(values); }
/// <summary> /// Определяет имеются ли записи логирования у переданного объекта /// </summary> /// <returns>True - записей нет, False - записи имеются</returns> private bool f_IsNew(I_ELog obj) { Cl_ELogClassAttribute classAtr = Cl_EntityLog.f_GetClassAttribute <Cl_ELogClassAttribute>(obj); if (classAtr == null) { return(false); } Cl_Log prevEvent = null; if (obj.p_GetLogEntityID != 0) { prevEvent = Cl_App.m_DataContext.p_Logs.Where(l => l.p_ElementID == obj.p_GetLogEntityID && l.p_EntityType == classAtr.p_EntityType).OrderByDescending(d => d.p_ChangeTime).FirstOrDefault(); } return(prevEvent == null); }
/// <summary> /// Установка первоначального объекта /// </summary> /// <param name="obj"></param> public void f_SetEntity(I_ELog obj) { if (logObject != null || obj == null) { return; } Cl_ELogClassAttribute classAtr = Cl_EntityLog.f_GetClassAttribute <Cl_ELogClassAttribute>(obj); if (classAtr == null) { return; } this.logObject = obj; this.entityLogType = classAtr.p_EntityType; lastValues = f_GetValues(logObject); }
/// <summary> /// Возвращает список измененных свойств объекта /// </summary> private Dictionary <PropertyInfo, object> f_GetChangedValues(I_ELog obj) { Dictionary <PropertyInfo, object> outValues = new Dictionary <PropertyInfo, object>(); Dictionary <PropertyInfo, object> currentValues = f_GetValues(obj); foreach (KeyValuePair <PropertyInfo, object> item in currentValues) { if (!lastValues.ContainsKey(item.Key)) { continue; } if (Cl_EntityCompare.f_IsCompare(item.Key.PropertyType, lastValues[item.Key], item.Value) == false) { outValues.Add(item.Key, item.Value); } } return(outValues); }
/// <summary> /// Вызывается после сохранения элемента, что бы определить какие изменения были сделаны /// </summary> /// <param name="obj"></param> public void f_SaveEntity(I_ELog obj, string textNew = null) { if (obj == null) { return; } Cl_ELogClassAttribute classAtr = Cl_EntityLog.f_GetClassAttribute <Cl_ELogClassAttribute>(obj); if (classAtr == null) { return; } Cl_Log newEvent = null; if (this.f_IsChanged(obj)) { StringBuilder sbAction = new StringBuilder(); if (f_IsNew(obj)) { if (!string.IsNullOrWhiteSpace(textNew)) { sbAction.AppendLine(textNew); } else { sbAction.AppendLine("Создан новый элемент"); } } else { Dictionary <PropertyInfo, object> changedValues = f_GetChangedValues(obj); foreach (KeyValuePair <PropertyInfo, object> item in changedValues) { Cl_ELogPropertyAttribute propAttr = item.Key.GetCustomAttributes(typeof(Cl_ELogPropertyAttribute), true).FirstOrDefault() as Cl_ELogPropertyAttribute; string action = ""; if (!propAttr.p_IsComputedLog) { if (propAttr.p_IsCustomDescription) { if (!string.IsNullOrEmpty(propAttr.p_Description)) { action = propAttr.p_Description + "."; } } else { action = "Изменилось поле: \""; if (string.IsNullOrEmpty(propAttr.p_Description)) { action += item.Key.Name + "\"."; } else { action += propAttr.p_Description + "\"."; } } } if (!propAttr.p_IgnoreValue) { if (!propAttr.p_IsNewValueOnly && propAttr.p_IsComputedLog == false) { action += " Старое значение: \"" + Cl_EntityValue.f_GetValue(item.Key, lastValues[item.Key], null) + "\"."; } action += (propAttr.p_IsComputedLog ? "" : " Новое значение: \"") + Cl_EntityValue.f_GetValue(item.Key, item.Value, lastValues[item.Key]) + (propAttr.p_IsComputedLog ? "" : "\"."); } sbAction.AppendLine(action); } } newEvent = f_CreateEvent(obj, sbAction.ToString().Trim()); } else { newEvent = f_CreateEvent(obj, "Без изменений"); } Cl_App.m_DataContext.p_Logs.Add(newEvent); Cl_App.m_DataContext.SaveChanges(); if (lastValues != null) { lastValues.Clear(); lastValues = f_GetValues(obj); } logObject = obj; }
public void Dispose() { lastValues.Clear(); lastValues = null; logObject = null; }
private static T f_GetClassAttribute <T>(I_ELog obj) { Type type = obj.GetType(); return((T)type.GetCustomAttributes(typeof(T), true).FirstOrDefault()); }