private void createObjectsFromLinks(XStorageObjectBase xobj) { // TODO: Здесь вопрос: удаленные объекты могут содержать линки с ссылками и, если да, то надо ли их обрабатывать ? if (xobj is XStorageObjectToDelete) { return; } XStorageObjectToSave xobjSave = (XStorageObjectToSave)xobj; foreach (DictionaryEntry entry in xobjSave.GetPropsByCapacity(XPropCapacity.Link, XPropCapacity.LinkScalar)) { Guid[] valueOIDs = (Guid[])entry.Value; if (valueOIDs.Length == 0) { continue; } string sPropName = (string)entry.Key; XPropInfoObjectLink propInfo = (XPropInfoObjectLink)xobj.TypeInfo.GetProp(sPropName); int nIndex = 0; foreach (Guid valueOID in valueOIDs) { XStorageObjectBase xobjValue = new XStorageObjectToSave(propInfo.ReferedType, valueOID, -1, false); xobjValue.Props[propInfo.ReverseProp.Name] = xobj.ObjectID; // пометим свойство специальным атрибутом, чтобы для него не выполнялась проверка на совпадение содержимого при мердже xobjValue.SetPropMergeMode(propInfo.ReverseProp.Name, XStorageObjectPropMergeModes.Weak); xobjValue = add(xobjValue); // упорядоченный линк ? - установим индексное свойство if (propInfo.OrderByProp != null) { xobjValue.Props[propInfo.OrderByProp.Name] = nIndex++; // пометим свойство специальным атрибутом, говорящим о том что при Merge'е данное значение затрет другое значение xobjValue.SetPropMergeMode(propInfo.OrderByProp.Name, XStorageObjectPropMergeModes.Replace); } } } }
private ArrayList normalizeObject(XStorageObjectBase xobj) { if (xobj is XStorageObjectToDelete) { return(null); } XStorageObjectToSave xobjSave = (XStorageObjectToSave)xobj; ArrayList aNewObjects = null; foreach (DictionaryEntry entry in xobjSave.GetPropsByCapacity(XPropCapacity.Link, XPropCapacity.LinkScalar)) { Guid[] valueOIDs = (Guid[])entry.Value; if (valueOIDs.Length == 0) { continue; } string sPropName = (string)entry.Key; XPropInfoObjectLink propInfo = (XPropInfoObjectLink)xobj.TypeInfo.GetProp(sPropName); int nIndex = 0; foreach (Guid valueOID in valueOIDs) { XStorageObjectBase xobjValue = (XStorageObjectBase)m_objectsDictionary[valueOID]; if (xobjValue == null) { // в датаграмме нет объекта, на который установлена ссылка в линке - значит создадим, этот объект точно не новый xobjValue = new XStorageObjectToSave(propInfo.ReferedType, valueOID, -1, false); if (aNewObjects == null) { aNewObjects = new ArrayList(); } aNewObjects.Add(xobjValue); // на случай если данный объект содержится еще в каком-нибудь линке m_objectsDictionary.Add(valueOID, xobjValue); } else { object vValue = xobjValue.Props[propInfo.ReverseProp.Name]; if (vValue == null || vValue == DBNull.Value) { // все хорошо - обратное свойство (объектный скаляр) пустое - установим его на текущий объект (xobj) xobjValue.Props[propInfo.ReverseProp.Name] = xobj.ObjectID; } else { Debug.Assert(vValue is Guid); // больше ничего другого быть не должно! // обратное свойство уже заполнено, проверим что оно ссылается на текущий объект. если это не так - ругаемся if (((Guid)vValue) != xobj.ObjectID) { throw new XInvalidXmlForestException("Ошибка при установке свойства " + propInfo.ReverseProp.Name + " объекта " + xobjValue.TypeInfo.Name + " [" + xobjValue.ObjectID + "]: нарушение согласованности со свойством " + sPropName + " объекта " + xobj.TypeInfo.Name + " [" + xobj.ObjectID + "]"); } } } // упорядоченный линк ? - установим индексное свойство if (propInfo.OrderByProp != null) { xobjValue.Props[propInfo.OrderByProp.Name] = nIndex++; } } } return(aNewObjects); }
public DomainPropLink(DomainObject objParent, XPropInfoObjectLink xpropInfo) : base(objParent, xpropInfo) { }