/// <summary> /// Осуществляет проверку на равенство с указанным объектом. /// </summary> /// <remarks>При сравнении не учитывается порядок следования объектов в коллекции.</remarks> /// <param name="obj">Объект, с которым требуется сравнить.</param> /// <returns>Флаг: <c>true</c>, если объекты равны, и <c>false</c>, в противном случае.</returns> public override bool Equals(object obj) { DataObjectDictionaryCollection anotherCollection = obj as DataObjectDictionaryCollection; if (anotherCollection == null) { return(false); } if (Count != anotherCollection.Count) { return(false); } List <DataObjectDictionary> alreadyCheckedDictionaries = new List <DataObjectDictionary>(); foreach (DataObjectDictionary anotherDictionary in anotherCollection) { foreach (DataObjectDictionary dictionary in this.Except(alreadyCheckedDictionaries)) { if (anotherDictionary.Equals(dictionary)) { alreadyCheckedDictionaries.Add(dictionary); break; } } } if (this.Except(alreadyCheckedDictionaries).Any()) { return(false); } return(true); }
/// <summary> /// Создает новую коллекцию словарей, представляющую объекты данных <see cref="DataObject"/>. /// </summary> /// <remarks> /// Типы значений в словарях коллекции, будут совпадать с типами значений в объектах данных. /// </remarks> /// <param name="jsonDataObjects">Строка, содержащая массив объектов данных в формате JSON (массив должен быть доступен по ключу "value").</param> /// <param name="dataObjectsView">Представление, по которому определены свойства для конвертации объектов в коллекцию словарей.</param> /// <param name="model">Edm-модель, указанная в ManagementToken.</param> /// <param name="castValues">Флаг: нужно ли приводить типы значений к типам объекта данных.</param> /// <returns>Новая коллекция словарей, представляющая объекты данных <see cref="DataObject"/>.</returns> public static DataObjectDictionaryCollection Parse(string jsonDataObjects, View dataObjectsView, DataObjectEdmModel model, bool castValues = true) { DataObjectDictionaryCollection result = new DataObjectDictionaryCollection(); if (jsonDataObjects == null || dataObjectsView == null) { return(result); } JavaScriptSerializer serializer = new JavaScriptSerializer(); Dictionary <string, object> dictionary = serializer.Deserialize <Dictionary <string, object> >(jsonDataObjects); object value; if (dictionary.TryGetValue("value", out value) && value is ArrayList) { Dictionary <string, object>[] dataObjects = ((ArrayList)value).Cast <Dictionary <string, object> >().ToArray(); DataObjectDictionary[] dataObjectsDictionaries = dataObjects .Select(x => DataObjectDictionary.Parse(serializer.Serialize(x), dataObjectsView, model, castValues)) .ToArray(); result.AddRange(dataObjectsDictionaries); } else { result.Add(DataObjectDictionary.Parse(jsonDataObjects, dataObjectsView, model, castValues)); } return(result); }
/// <summary> /// Инициализирует словарь, представляющий объект данных <see cref="DataObject"/> в виде словаря <see cref="Dictionary{String,Object}"/>. /// </summary> /// <remarks> /// Используется для преобразования типов значений из словаря, полученного через стандартный десериализатор. /// </remarks> /// <param name="dataObjectAliases">Объект данных, в виде словаря псевдонимов.</param> /// <param name="dataObjectView">Представление, по которому определены свойства для конвертации объекта в словарь.</param> /// <param name="model">Edm-модель, указанная в ManagementToken.</param> /// <param name="serializeValues">Флаг: Нужно ли сериализовывать значения свойств объекта.</param> private DataObjectDictionary(Dictionary <string, object> dataObjectAliases, View dataObjectView, DataObjectEdmModel model, bool serializeValues = false) : base() { if (dataObjectAliases == null || dataObjectView == null) { return; } Type dataObjectType = dataObjectView.DefineClassType; List <string> viewAllPropertiesNames = dataObjectView.GetSelfAllPropertiesNames(); if (dataObjectAliases.Keys.Count != viewAllPropertiesNames.Count) { throw new Exception(string.Format( "Received dataObject properties count is different from expected count. Received {0}, but {1} is expected.", dataObjectAliases.Keys.Count, viewAllPropertiesNames.Count)); } for (int i = 0; i < dataObjectAliases.Keys.Count; i++) { string aliasPropertyName = dataObjectAliases.Keys.ElementAt(i); string dataObjectPropertyName = model.GetDataObjectPropertyName(dataObjectType, aliasPropertyName); if (!viewAllPropertiesNames.Contains(dataObjectPropertyName)) { throw new Exception(string.Format( "Received dataObject contains unexpected property. Property name is \"{0}\", but expected properties are: {1}.", dataObjectPropertyName, string.Concat("\"", string.Join("\", \"", viewAllPropertiesNames), "\""))); } object dataObjectPropertyValue = dataObjectAliases[aliasPropertyName]; Type dataObjectPropertyType = Information.GetPropertyType(dataObjectView.DefineClassType, dataObjectPropertyName); if (dataObjectPropertyType.IsSubclassOf(typeof(DataObject))) { Dictionary <string, object> master = dataObjectPropertyValue as Dictionary <string, object>; Add(aliasPropertyName, master != null ? new DataObjectDictionary(master, dataObjectView.GetSelfMasterView(dataObjectPropertyName), model, serializeValues) : null); continue; } if (dataObjectPropertyType.IsSubclassOf(typeof(DetailArray))) { Dictionary <string, object>[] details = (dataObjectPropertyValue as ArrayList)?.Cast <Dictionary <string, object> >().ToArray() ?? new Dictionary <string, object>[] { }; DataObjectDictionary[] detailsDictionaries = details .Select(x => new DataObjectDictionary(x, dataObjectView.GetDetail(dataObjectPropertyName).View, model, serializeValues)) .ToArray(); DataObjectDictionaryCollection detailsCollection = new DataObjectDictionaryCollection(); detailsCollection.AddRange(detailsDictionaries); Add(aliasPropertyName, detailsCollection); continue; } if (serializeValues) { Add(aliasPropertyName, dataObjectPropertyValue?.ToString()); continue; } if (dataObjectPropertyValue == null) { Add(aliasPropertyName, null); continue; } Type actualPropertyType = dataObjectPropertyValue.GetType(); if (actualPropertyType == dataObjectPropertyType) { Add(aliasPropertyName, dataObjectPropertyValue); continue; } if (dataObjectPropertyType.IsEnum && actualPropertyType == typeof(string)) { Add(aliasPropertyName, Enum.Parse(dataObjectPropertyType, (string)dataObjectPropertyValue)); continue; } MethodInfo dataObjectPropertyParseMethod = dataObjectPropertyType.GetMethod("Parse", new[] { typeof(string) }); if (dataObjectPropertyParseMethod != null && actualPropertyType == typeof(string)) { Add(aliasPropertyName, dataObjectPropertyParseMethod.Invoke(null, new[] { dataObjectPropertyValue })); continue; } ConstructorInfo dataObjectPropertyConstructor = dataObjectPropertyType.GetConstructor(new[] { actualPropertyType }); if (dataObjectPropertyConstructor != null) { Add(aliasPropertyName, dataObjectPropertyConstructor.Invoke(new[] { dataObjectPropertyValue })); continue; } } }