/// <summary> /// Извлечение объекта данных из строки /// </summary> /// <param name="xmlEl"> Текущий элемент xml </param> /// <param name="dataObject"> Текущий объект данных </param> /// <param name="assemblies"> Необходимые сборки </param> /// <param name="DataObjectCache"> DataObjectCache </param> /// <param name="deserializedObjectsList"> Словарь десериализованных объектов с их первичными ключами </param> private static void prv_XmlElement2DataObject( XmlElement xmlEl, ICSSoft.STORMNET.DataObject dataObject, SortedList assemblies, DataObjectCache DataObjectCache, Dictionary <string, ICSSoft.STORMNET.DataObject> deserializedObjectsList) { if (!deserializedObjectsList.ContainsKey(dataObject.__PrimaryKey.ToString())) { deserializedObjectsList.Add(dataObject.__PrimaryKey.ToString(), dataObject); } var storableprops = new ArrayList(Information.GetStorablePropertyNames(dataObject.GetType())); var order = new StringCollection(); order.AddRange(Information.GetLoadingOrder(dataObject.GetType())); foreach (string propname in order) { // Прочитка в соответствии с указанным порядком prv_ReadProperty(xmlEl, dataObject, propname, assemblies, DataObjectCache, deserializedObjectsList); } XmlAttributeCollection xmlattributes = xmlEl.Attributes; XmlNodeList xmlchilds = xmlEl.ChildNodes; if (xmlattributes != null) { foreach (XmlAttribute xmlattribute in xmlattributes) { if (!order.Contains(xmlattribute.Name) && storableprops.Contains(xmlattribute.Name)) { prv_ReadAttribute(xmlattribute, dataObject); } } } if (xmlchilds != null) { foreach (XmlNode xmlchild in xmlchilds) { Type proptype = Information.GetPropertyType(dataObject.GetType(), xmlchild.Name); if (proptype.IsSubclassOf(typeof(DataObject))) { // Это мастер prv_ReadMaster(xmlchild, dataObject, assemblies, DataObjectCache, deserializedObjectsList); } else { // Это детейл if (!order.Contains(xmlchild.Name)) { var detail = (DetailArray)Information.GetPropValueByName(dataObject, xmlchild.Name); XmlNodeList xmldetailobjects = xmlchild.ChildNodes; if (xmldetailobjects != null) { prv_ReadDetail(xmldetailobjects, detail, assemblies, DataObjectCache, deserializedObjectsList); } } } } } if (xmlEl.HasAttribute("DynamicProperties")) { if (xmlEl.HasAttribute("DynamicProperties")) { string dpstr = xmlEl.GetAttribute("DynamicProperties"); if (string.IsNullOrEmpty(dpstr)) { dataObject.DynamicProperties = new NameObjectCollection(); } else { dataObject.DynamicProperties = (NameObjectCollection)ObjectFromString(dpstr); } } } dataObject.InitDataCopy(); dataObject.SetLoadingState(LoadingState.Loaded); dataObject.SetStatus(ObjectStatus.UnAltered); }
/// <summary> /// Получение XML документа из объекта данных /// </summary> /// <param name="xmlEl"> Текущий XmlElement, куда записываются данные и от которого создаются потомки </param> /// <param name="dataObject"> Сериализуемый объект данных </param> /// <param name="assemblies"> Имена сборок (будут записаны в xml) </param> /// <param name="serializeAggregators"> Следует ли сериализовать детейлы </param> /// <param name="setObjectLoadingStateLoaded"> Установить LoadingState объекта в Loaded </param> /// <param name="setObjectStatusCreated"> Установить ObjectStatus объекта в Created </param> /// <param name="serializeMasters"> Сериализовать мастеров объектов </param> /// <param name="usedPrimaryKeyList"> Вспомогательный список первичных ключей объектов, которые уже были сериализованы </param> /// <returns> Сериализованное представление объекта </returns> private static void prv_DataObject2XmlElement( XmlElement xmlEl, ICSSoft.STORMNET.DataObject dataObject, SortedList assemblies, bool serializeAggregators, bool setObjectLoadingStateLoaded, bool setObjectStatusCreated, bool serializeMasters, ICollection <string> usedPrimaryKeyList) { if (serializeMasters && usedPrimaryKeyList.Contains(dataObject.__PrimaryKey.ToString())) { // Это значит, что данный объект уже был сериализован (это надстройка для адекватной сериализации мастеров) xmlEl.SetAttribute("Type", dataObject.GetType().ToString()); xmlEl.SetAttribute("__PrimaryKey", dataObject.__PrimaryKey.ToString()); return; } if (serializeMasters) { // Надстройка для адекватной сериализации мастеров usedPrimaryKeyList.Add(dataObject.__PrimaryKey.ToString()); } string[] propNames = Information.GetStorablePropertyNames(dataObject.GetType()); for (int i = 0; i < propNames.Length; i++) { PropertyInfo propertyinfo = dataObject.GetType().GetProperty(propNames[i]); if (!prv_IsAgregator(propertyinfo) || serializeAggregators) { if (propertyinfo.PropertyType.IsSubclassOf(typeof(DetailArray))) { // Значит, это детейлы var xmlElDetailArray = (XmlElement)xmlEl.AppendChild(xmlEl.OwnerDocument.CreateElement(propNames[i])); var detailarray = (ICSSoft.STORMNET.DetailArray)Information.GetPropValueByName(dataObject, propNames[i]); if (detailarray != null) { int j = 0; while (j < detailarray.Count) { if (detailarray.ItemByIndex(j).GetStatus() != ObjectStatus.Deleted) { // Удалённые объекты сохранять не следует string strtype = detailarray.ItemByIndex(j).GetType().ToString(); var xmlElDetailObject = (XmlElement)xmlElDetailArray.AppendChild(xmlEl.OwnerDocument.CreateElement(strtype)); if (!assemblies.ContainsKey(strtype)) { assemblies.Add(strtype, detailarray.ItemByIndex(j).GetType().Assembly.FullName); } prv_DataObject2XmlElement( xmlElDetailObject, detailarray.ItemByIndex(j), assemblies, serializeAggregators, setObjectLoadingStateLoaded, setObjectStatusCreated, serializeMasters, usedPrimaryKeyList); } else { // Тогда нужно грохнуть из массива detailarray.Remove(detailarray.ItemByIndex(j)); j--; } j++; } } } else { if (propertyinfo.PropertyType.IsSubclassOf(typeof(DataObject))) { // Значит, это мастер object mastervalue = Information.GetPropValueByName(dataObject, propNames[i]); if (mastervalue != null) { string mastertype = mastervalue.GetType().ToString(); if (!assemblies.ContainsKey(mastertype)) { assemblies.Add(mastertype, mastervalue.GetType().Assembly.FullName); } var xmlElMaster = (XmlElement)xmlEl.AppendChild(xmlEl.OwnerDocument.CreateElement(propNames[i])); var masterDataObject = (DataObject)Information.GetPropValueByName(dataObject, propNames[i]); if (!serializeMasters) { // Старое поведение, которое не сериализует мастеров xmlElMaster.SetAttribute("Type", mastervalue.GetType().ToString()); xmlElMaster.SetAttribute("__PrimaryKey", masterDataObject.__PrimaryKey.ToString()); } else { // Новое поведение, которое будет сериализовать мастеров if (!usedPrimaryKeyList.Contains(masterDataObject.__PrimaryKey.ToString())) { xmlElMaster.SetAttribute("__Type", mastervalue.GetType().ToString()); } prv_DataObject2XmlElement( xmlElMaster, masterDataObject, assemblies, serializeAggregators, setObjectLoadingStateLoaded, setObjectStatusCreated, serializeMasters, usedPrimaryKeyList); } } } else { // Значит, это собственный атрибут object propvalue = Information.GetPropValueByName(dataObject, propNames[i]) ?? string.Empty; xmlEl.SetAttribute(propNames[i], propvalue.ToString()); } } } } xmlEl.SetAttribute("DynamicProperties", dataObject.DynamicProperties.Count > 0 ? ObjectToString(dataObject.DynamicProperties) : string.Empty); if (setObjectLoadingStateLoaded) { dataObject.SetLoadingState(LoadingState.Loaded); } if (setObjectStatusCreated) { dataObject.SetStatus(ObjectStatus.Created); } }