/// <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);
        }
Beispiel #3
0
        /// <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;
                }
            }
        }