private static void GetFullChildPropertyChanges(AuditChange mainChange, DateTime from, DateTime until) { if (mainChange != null) { var mastersKeys = new List <string>(); mastersKeys.AddRange(mainChange.MastersChanges.Keys); foreach (var masterChangeKey in mastersKeys) { var objKey = mainChange.MastersChanges[masterChangeKey].ObjPrimaryKey; mainChange.MastersChanges[masterChangeKey] = GetChangesByPeriodByPK(from, until, objKey, true, true); } var detailsKeys = new List <string>(); detailsKeys.AddRange(mainChange.DetailsChanges.Keys); foreach (var detailChangeKey in detailsKeys) { var objKey = mainChange.DetailsChanges[detailChangeKey].ObjPrimaryKey; mainChange.DetailsChanges[detailChangeKey] = GetChangesByPeriodByPK(from, until, objKey, true, true); } } }
private static AuditChange GetChangesByPeriodByPK(DateTime from, DateTime until, string objPk, bool firstLoop, bool recursive) { var операцииЗаПериод = new List <AuditEntity>(); try { var lcs = LoadingCustomizationStruct.GetSimpleStruct(typeof(AuditEntity), AuditEntity.Views.AuditEntityE); lcs.LimitFunction = FunctionBuilder.BuildAnd( FunctionBuilder.BuildEquals(nameof(AuditEntity.ObjectPrimaryKey), objPk), FunctionBuilder.BuildBetween <AuditEntity>(x => x.OperationTime, from, until)); операцииЗаПериод = DataService.LoadObjects(lcs).Cast <AuditEntity>().OrderBy(x => x.OperationTime) .ToList(); } catch (Exception ex) { LogService.LogError( $@"Произошла ошибка при попытке получить изменения за период {from.ToShortDateString()} - { until.ToShortDateString() } для объекта с ключом {objPk}.{Environment.NewLine}{ex.Message}"); } var итоговыйСтатусОбъекта = GetAuditOperationType(операцииЗаПериод); var изменениеОбъекта = new AuditChange { Type = GetObjTypeByPK(objPk), ObjPrimaryKey = objPk, Operation = итоговыйСтатусОбъекта }; if (итоговыйСтатусОбъекта != tAuditOperation.CreateAndDelete && итоговыйСтатусОбъекта != tAuditOperation.NoChange && (firstLoop || recursive)) { var fieldsLcs = LoadingCustomizationStruct.GetSimpleStruct(typeof(AuditField), ViewForField); foreach (var операцияИзменения in операцииЗаПериод) { var измененияПолей = new List <AuditField>(); try { fieldsLcs.LimitFunction = FunctionBuilder.BuildEquals <AuditField>(x => x.AuditEntity, операцияИзменения); измененияПолей = DataService.LoadObjects(fieldsLcs).Cast <AuditField>().ToList(); } catch (Exception ex) { LogService.LogError( $@"Произошла ошибка при попытке получить набор изменения изменения полей за период { from.ToShortDateString() } - {until.ToShortDateString()} для объекта с ключом {objPk} для изменения с ключом { операцияИзменения.__PrimaryKey }.{Environment.NewLine}{ex.Message}"); } var толькоСобственныеИзменения = измененияПолей.Where( y => y.MainChange != null || !измененияПолей.Exists(x => PKHelper.EQPK(x.MainChange, y))); foreach (var измененныйАтрибут in толькоСобственныеИзменения) { if (измененныйАтрибут.MainChange == null) { // Это изменение собственного поля. изменениеОбъекта.FieldsChanges[измененныйАтрибут.Field] = измененныйАтрибут.NewValue; } else { var главноеИзменение = измененияПолей.First(x => PKHelper.EQPK(x, измененныйАтрибут.MainChange)); if (Regex.IsMatch(главноеИзменение.Field, "[ ][(][0-9]+[)]$")) { // Это изменение детейла. var номерДетейла = Regex.Match(главноеИзменение.Field, "[ ][(][0-9]+[)]$").Value; // Если ссылка на детейл стала нулл, то соберём изменение удаления этого объекта. var ключДетейла = измененныйАтрибут.NewValue == "-NULL-" ? измененныйАтрибут.OldValue : измененныйАтрибут.NewValue; // Заменяем номер детейла на ключ объекта. Так как номер переприсваевается следующими по порядку детейлу, // в качестве ключа изменения детейла используем тип детейла и его первичного ключа заключенный в между@@ изменениеОбъекта.DetailsChanges[ главноеИзменение.Field.Replace(номерДетейла, $"@{ключДетейла}@")] = GetChangesByPeriodByPK(from, until, ключДетейла, false, recursive); } else { // Это изменение мастера. // Если ссылка на мастра стала нулл, то и изменения не будем собирать, возвращаем нулл. изменениеОбъекта.MastersChanges[главноеИзменение.Field] = измененныйАтрибут.NewValue == "-NULL-" ? null : GetChangesByPeriodByPK(from, until, измененныйАтрибут.NewValue, false, recursive); } } } } } return(изменениеОбъекта); }