public void GetHashCodeСравнениеХэшОбъекта() { var obj = new DataObjectForTest(); Assert.Equal( PKHelper.GetKeyByObject(obj).ToString().ToLower().GetHashCode(), new PKComparer <DataObjectForTest>().GetHashCode(obj)); }
public void BuildNotEqualsTest14() { Assert.Equal( LangDef.GetFunction( LangDef.funcNEQ, PrimaryKeyVarDef, PKHelper.GetKeyByObject(KeyGuid1)), FunctionBuilder.BuildNotEquals(KeyGuid1)); }
public void BuildEqualsTest24() { Assert.Equal( LangDef.GetFunction( LangDef.funcEQ, GuidVarDef, PKHelper.GetKeyByObject(Guid1)), FunctionBuilder.BuildEquals(PropertyName, Guid1)); }
public void BuildNotEqualsTest26() { Assert.Equal( LangDef.GetFunction( LangDef.funcNEQ, GuidVarDef, PKHelper.GetKeyByObject(TestDataObject1)), FunctionBuilder.BuildNotEquals(PropertyName, TestDataObject1)); }
public void BuildEqualsTest12() { Assert.Equal( LangDef.GetFunction( LangDef.funcEQ, PrimaryKeyVarDef, PKHelper.GetKeyByObject(GuidString)), FunctionBuilder.BuildEquals(GuidString)); }
public void BuildEqualsTest15() { Assert.Equal( LangDef.GetFunction( LangDef.funcEQ, PrimaryKeyVarDef, PKHelper.GetKeyByObject(TestDataObject1)), FunctionBuilder.BuildEquals(TestDataObject1)); }
/// <summary> /// Проверить и преобразовать аргумент в соответствии с типом. /// </summary> /// <param name="type">Тип.</param> /// <param name="value">Значение.</param> /// <exception cref="ArgumentException">Аргумент не содержит ключевой структуры.</exception> /// <exception cref="InvalidCastException">Не совпадают тип свойства и тип переданного параметра.</exception> /// <exception cref="FormatException"><seealso cref="M:Convert.ChangeType(object, Type)"/></exception> /// <returns>Преобразованный аргумент.</returns> internal static object ConvertValue(Type type, object value) { ValidateValue(value); var nctType = GetObjectType(type).NetCompatibilityType; var res = value; if (res.GetType().IsEnum) { if (nctType == typeof(string)) { res = EnumCaption.GetCaptionFor(res); } else if (nctType == typeof(decimal)) { res = Convert.ChangeType(res, nctType); } } if (IsKeyType(nctType)) { res = PKHelper.GetKeyByObject(res); if (res == null) { throw new ArgumentException(nameof(value)); } } ValidateValue(res); // Когда свойство строкового типа, а значение - не строка. if (nctType == typeof(string) && GetObjectType(res.GetType()).NetCompatibilityType != typeof(string)) { res = Convert.ToString(res); } if (GetObjectType(res.GetType()).NetCompatibilityType != nctType) { if (res.GetType().GetInterfaces().Any(x => x == typeof(IConvertible))) { // Попробуем преобразовать в нужный тип. res = Convert.ChangeType(res, type); } else { throw new InvalidCastException(nameof(value)); } } return(res); }
public void BuildEqualsTest54() { Assert.Equal( LangDef.GetFunction(LangDef.funcEQ, GuidGenVarDef, PKHelper.GetKeyByObject(KeyGuid1)), FunctionBuilder.BuildEquals <TestDataObject>(x => x.Hierarchy, KeyGuid1)); }
public void BuildEqualsTest47() { Assert.Equal( LangDef.GetFunction(LangDef.funcEQ, GuidVarDef, PKHelper.GetKeyByObject(TestDataObject1)), FunctionBuilder.BuildEquals(GuidVarDef, TestDataObject1)); }
public void BuildBetweenTest14() { Assert.Equal( LangDef.GetFunction(LangDef.funcBETWEEN, GuidVarDef, PKHelper.GetKeyByObject(Guid1), PKHelper.GetKeyByObject(TestDataObject1)), FunctionBuilder.BuildBetween(GuidVarDef, Guid1, TestDataObject1)); }
public void BuildBetweenTest313() { Assert.Equal( LangDef.GetFunction(LangDef.funcBETWEEN, GuidVarDef, PKHelper.GetKeyByObject(Guid1), KeyGuid1), FunctionBuilder.BuildBetween(GuidVarDef.Caption, Guid1, KeyGuid1)); }
public void BuildBetweenTest107() { Assert.Equal( LangDef.GetFunction(LangDef.funcBETWEEN, GuidGenVarDef, PKHelper.GetKeyByObject(Guid1), PKHelper.GetKeyByObject(Guid2)), FunctionBuilder.BuildBetween <TestDataObject>(x => x.Hierarchy, Guid1, Guid2)); }
public void BuildTest74() { Assert.Equal( LangDef.GetFunction(LangDef.funcIN, GuidVarDef, PKHelper.GetKeyByObject(Guid1), PKHelper.GetKeyByObject(Guid2)), FunctionBuilder.Build(LangDef.funcIN, GuidVarDef, GuidList.ToArray(), GuidList.ToArray())); }
public void ConvertValueTest13() { Assert.Equal( PKHelper.GetKeyByObject(TestKeyGuid), FunctionHelper.ConvertValue(GuidType.NetCompatibilityType, TestKeyGuid)); }
public void BuildNotEqualsTest36() { Assert.Equal( LangDef.GetFunction(LangDef.funcNEQ, GuidVarDef, PKHelper.GetKeyByObject(KeyGuid1)), FunctionBuilder.BuildNotEquals(PropertyName, LangDef.GuidType, KeyGuid1)); }
public void GetGuidByObjectСравнениеString() { Assert.True( PKHelper.EQPK(str1, PKHelper.GetKeyByObject(str1)), "Возвращенный Guid не равен исходному string."); }
public void BuildNotEqualsTest45() { Assert.Equal( LangDef.GetFunction(LangDef.funcNEQ, GuidVarDef, PKHelper.GetKeyByObject(Guid1)), FunctionBuilder.BuildNotEquals(GuidVarDef, Guid1)); }
public void BuildTest87() { Assert.Equal( LangDef.GetFunction(LangDef.funcIN, GuidVarDef, KeyGuid1, KeyGuid2, PKHelper.GetKeyByObject(Guid1), PKHelper.GetKeyByObject(Guid2)), FunctionBuilder.Build(LangDef.funcIN, GuidVarDef, KeyGuidList.Where(x => true), GuidList.ToArray())); }
public void BuildTest79() { Assert.Equal( LangDef.GetFunction(LangDef.funcIN, GuidVarDef, KeyGuid1, KeyGuid2, PKHelper.GetKeyByObject(Guid1), PKHelper.GetKeyByObject(Guid2)), FunctionBuilder.Build(LangDef.funcIN, GuidVarDef, KeyGuidList, GuidList)); }
public void ConvertValueTest04() { Assert.Equal( PKHelper.GetKeyByObject(TestTestDataObject), FunctionHelper.ConvertValue(DataObjectType.NetCompatibilityType, TestTestDataObject)); }
public void GetKeyByObjectСравнениеGuid() { Assert.True( PKHelper.EQPK(g1, PKHelper.GetKeyByObject(g1)), "Возвращенный KeyGuid не равен исходному Guid."); }
/// <summary> /// Получить объект на заданную дату. /// </summary> /// <param name="date">Дата на которую следует откатить состояние объекта</param> /// <param name="obj">Объект, который откатываем на заданную дату.</param> /// <param name="onlySelfObj">Откатывать только сам объект, т.е. в обратное состояния вернутся все собственные поля объекта и все собственные ссылочные объекты(мастра и детейлы) только ключи</param> /// <param name="forceNullAgregator">Объект вернётся в состояние сразу после заданной даты. /// Если откатываем создание объекта, то возвращаем путой объект с первичным ключом. /// Если объект был удалён и ведётся аудит удаления, то он будет восстановлен со всеми своими собственными полями, иначе если аудит удаления отключен, у удаленного объекта будет проинициализирован только первичный ключ. /// </param> public static void GetObjForDate(DateTime date, ref DataObject obj, bool onlySelfObj = true, bool forceNullAgregator = false) { if (obj != null) { var objType = obj.GetType(); try { obj.DisableInitDataCopy(); // Не кидается исключение о не существовании объекта, если объект был удалён и ведётся аудит удаления, то он будет восстановлен со всеми своими собственными полями, иначе если аудит удаления отключен, у удаленного объекта будет проинициализирован только первичный ключ. DataServiceFactory.AppDataService.LoadObject(new View(objType, View.ReadType.WithRelated), obj, true, false); } catch (Exception ex) { throw new Exception($"Ошибка при попытке вычитать изменнённый объект из БД. {ex.Message}"); } List <AuditEntity> changedAuditEntity; try { var lcs = LoadingCustomizationStruct.GetSimpleStruct(typeof(AuditEntity), AuditEntity.Views.AuditEntityE); lcs.LimitFunction = FunctionBuilder.BuildAnd( #pragma warning disable CS0618 // Используем не дженерик вариант, иначе не работает вычитка FunctionBuilder.BuildEquals(nameof(AuditEntity.ObjectPrimaryKey), obj.__PrimaryKey), #pragma warning restore CS0618 // Тип или член устарел FunctionBuilder.BuildGreater <AuditEntity>(x => x.OperationTime, date)); // Загружаем изменения строго больше даты на которую хотим откатить => получаем объект в состоянии сразу после этой даты. lcs.ColumnsSort = new[] { new ColumnsSortDef(nameof(AuditEntity.OperationTime), SortOrder.Desc) }; changedAuditEntity = DataServiceFactory.AppDataService.LoadObjects(lcs).Cast <AuditEntity>().ToList(); } catch (Exception ex) { throw new Exception( $"Ошибка при попытке загрузить операции изменения {nameof(AuditEntity)} для объекта({obj.__PrimaryKey}). {ex.Message}"); } var auditFieldsLcs = LoadingCustomizationStruct.GetSimpleStruct(typeof(AuditField), ViewForField); foreach (var changeEntity in changedAuditEntity) { if (changeEntity.OperationType != OperationCreateType) { List <AuditField> changedFields; try { // Загружаем набор изменившихся полей из аудита auditFieldsLcs.LimitFunction = FunctionBuilder.BuildEquals <AuditField>(x => x.AuditEntity, changeEntity); changedFields = DataServiceFactory.AppDataService.LoadObjects(auditFieldsLcs) .Cast <AuditField>().ToList(); } catch (Exception ex) { throw new Exception( $"Произошла ошибка при попытке получить набор изменений полей для операции аудита:{PKHelper.GetGuidByObject(changeEntity)}. {ex.Message}"); } //Берём только изменения, вспомогательные объекты LinkedPrimaryKey остаются в основном списке. var onlySelfChangedFields = changedFields.Where(y => y.MainChange == null); foreach (var changedField in onlySelfChangedFields) { var mainChange = changedFields.FirstOrDefault(x => PKHelper.EQPK(x.MainChange, changedField)); if (mainChange == null) { //Если основного изменения нет, то это обычное поле var propertyInfo = objType.GetProperty(changedField.Field); if (propertyInfo != null) { var typeprop = propertyInfo.PropertyType; object value = null; try { if (changedField.OldValue != null) { if (typeprop.IsEnum) { value = EnumCaption.GetValueFor(changedField.OldValue, typeprop); } else if (typeprop == typeof(NullableDateTime)) { value = NullableDateTime.Parse(changedField.OldValue); } else if (typeprop == typeof(NullableInt)) { value = NullableInt.Parse(changedField.OldValue); } else { value = Convert.ChangeType(changedField.OldValue, typeprop, CultureInfo.InvariantCulture); } } propertyInfo.SetValue(obj, value); } catch (Exception ex) { var errorText = value != null ? $"AuditField:{PKHelper.GetGuidByObject(changedField)} Ошибка при попытке установить значение поля {value} в объект {objType.Name}:{PKHelper.GetGuidByObject(obj)} поле {changedField.Field}" : $"AuditField:{PKHelper.GetGuidByObject(changedField)} Ошибка при попытке преобразовать значение поля {changedField.OldValue} в тип {typeprop.Name}"; throw new Exception($"{errorText}. {ex.Message}"); } } else { throw new Exception( $"Ошибка - не найдено поле {changedField.Field} в объекте {objType.Name}."); } } else { // Есть основное изменение, значит это изменение ссылочного объекта. // Только если изменилась ссылка if (mainChange.OldValue != mainChange.NewValue) { // В аудите детейл отличается от мастера тем, что у него приписывается в скобках позиция if (Regex.IsMatch(changedField.Field, "[ ][(][0-9]+[)]$")) { // Это изменение детейла объекта. var separateIndex = changedField.Field.IndexOf(" ", StringComparison.Ordinal); var detailNameFromField = changedField.Field.Substring(0, separateIndex); var propertyInfo = objType.GetProperty(detailNameFromField); if (propertyInfo != null) { if (propertyInfo.GetValue(obj) is DetailArray detailValue) { if (changedField.OldValue == "-NULL-") { var key = new KeyGuid(mainChange.NewValue); try { if (detailValue.GetByKey(key) != null) { detailValue.RemoveByKey(key); } } catch (Exception ex) { throw new Exception( $"Ошибка при попытке удалить объект с ключом {key} из детейла {detailNameFromField} в объекте {objType.Name}. {ex.Message}"); } } else { var detailItemType = detailValue.ItemType; var oldDetailObj = Helper.CreateDataObject(detailItemType, mainChange.OldValue); try { var oldObjKey = PKHelper.GetKeyByObject(oldDetailObj); if (detailValue.GetByKey(oldObjKey) == null) { detailValue.AddObject(oldDetailObj); } else { detailValue.SetByKey(oldObjKey, oldDetailObj); } } catch (Exception ex) { throw new Exception( $"Ошибка при добавить объект с ключом {PKHelper.GetGuidByObject(oldDetailObj)} в детейл {detailNameFromField} в объекте {objType.Name}. {ex.Message}"); } } } } else { throw new Exception( $"Ошибка - не найден детейл {detailNameFromField} в объекте {objType.Name}."); } } else { // Это изменение мастера объекта. var propertyInfo = objType.GetProperty(changedField.Field); if (propertyInfo != null) { //Это свойство является агрегатором, для детейла var itIsAgregator = propertyInfo.GetCustomAttribute <AgregatorAttribute>() != null; if (changedField.OldValue == "-NULL-" || forceNullAgregator && itIsAgregator) { //Если свойство является агрегатором для детейла, то в последующих витках рекурсии всегда возвращаем нулл для такого поля, во избежание циклических ссылок. propertyInfo.SetValue(obj, null); } else { var typeprop = propertyInfo.PropertyType; var oldMasterObj = Helper.CreateDataObject(typeprop, mainChange.OldValue); try { propertyInfo.SetValue(obj, oldMasterObj); } catch (Exception ex) { throw new Exception( $"Ошибка при попытке установить свойство мастера {changedField.Field} в объекте {objType.Name}. {ex.Message}"); } } } else { throw new Exception( $"Ошибка - не найден мастер {changedField.Field} в объекте {objType.Name}."); } } } } } } else { // Если откатываем создание объекта, то возвращаем путой объект с первичным ключом. obj = Helper.CreateDataObject(objType, obj.__PrimaryKey); } } // На этом этапе основной объект и все его собственные поля и зависимые сущности возвращены на дату // Получаем мастера и откатываем их поля, рекурсивно вызывая этот метод // Получаем детейлы объекта и откатываем их поля, рекурсивно вызывая этот метод if (!onlySelfObj && changedAuditEntity.Any()) { var objProperties = objType.GetProperties(); foreach (var property in objProperties) { var typeprop = property.PropertyType; if (typeprop.IsSubclassOf(typeof(DataObject))) { //Перебираем все мастера var masterValue = property.GetValue(obj) as DataObject; GetObjForDate(date, ref masterValue, false, true); } else if (typeprop.IsSubclassOf(typeof(DetailArray))) { //Перебираем все детейлы if (property.GetValue(obj) is DetailArray detailValue) { var detailObjects = detailValue.GetAllObjects(); foreach (var dataObject in detailObjects) { var currentObj = dataObject; GetObjForDate(date, ref currentObj, false, true); } } } } } } }