/// <summary> /// 初始化必要的构造参数。 /// </summary> public SqlBuilder() { AliasCache = new ReferenceCache <string>(); Builder = new StringBuilder(); XTypeInfo = XTypeInfo.Create(GetType(), XBindingFlags.Default | XBindingFlags.NonPublic); aliasIndex = 0; }
static AspNetJsonExecutor() { var xTypeInfo = XTypeInfo.Create <TJsonResult>( XBindingFlags.Public | XBindingFlags.Instance | XBindingFlags.Property); valueProperty = xTypeInfo.GetProperty("Value") ?? xTypeInfo.GetProperty("Data") ?? throw new NotSupportedException("Value"); settingsProperty = xTypeInfo.GetProperty("SerializerSettings") ?? throw new NotSupportedException("SerializerSettings"); statusProperty = xTypeInfo.GetProperty("StatusCode") ?? throw new NotSupportedException("StatusCode"); contentTypeProperty = xTypeInfo.GetProperty("ContentType") ?? throw new NotSupportedException("ContentType"); }
protected DomainObjectFactory m_InstanceFactory; // "Фабрика" объектов public Mapper(XTypeInfo xtype, DomainObjectFactory factory) { m_xtypeInfo = xtype; if (m_InstanceFactory == null) { m_InstanceFactory = new DomainObjectFactory(m_xtypeInfo); } else { m_InstanceFactory = factory; } }
public XStorageObjectToSave(XTypeInfo typeInfo, Guid oid, Int64 ts, bool bNew) : base(typeInfo, oid, ts) { if (bNew) { m_state = XStorageObjectState.ToInsert; } else { m_state = XStorageObjectState.ToUpdate; } m_bUpdateTS = true; }
/// <summary> /// Добавляет ко множеству xml-объект /// </summary> /// <param name="xmlObject"></param> private void Add(XmlElement xmlObject, XTypeInfo typeInfo) { XStorageObjectBase xobj = CreateXStorageObject(xmlObject, typeInfo); XStorageObjectBase xobjExists = (XStorageObjectBase)m_objectsDictionary[xobj.ObjectID]; if (xobjExists != null) { merge(xobjExists, xobj); } else { m_objects.Add(xobj); m_objectsDictionary.Add(xobj.ObjectID, xobj); } }
public void TypeTest() { var xTypeInfo = XTypeInfo.Create <Tester>(XBindingFlags.Default | XBindingFlags.Static | XBindingFlags.NonPublic); var obj = new Tester(); obj.public_event_action += null; xTypeInfo.GetEvent("public_event_func").AddEventHandler(obj, null); xTypeInfo.GetEvent("public_event_func").AddEventHandler(obj, null); Assert.AreEqual(2, obj.public_event_func_count); xTypeInfo.GetEvent("public_event_func").RemoveEventHandler(obj, null); Assert.AreEqual(1, obj.public_event_func_count); xTypeInfo.GetField("private_field_string").SetValue(obj, "F**k"); Assert.AreEqual("F**k", xTypeInfo.GetField("private_field_string").GetValue(obj)); xTypeInfo.GetField("public_field_int").SetValue(obj, 999); Assert.AreEqual(999, xTypeInfo.GetField("public_field_int").GetValue(obj)); xTypeInfo.GetProperty("public_property_int").SetValue(obj, 123); Assert.AreEqual(123, xTypeInfo.GetProperty("public_property_int").GetValue(obj)); xTypeInfo.GetProperty("private_property_string").SetValue(obj, "Dogwei"); Assert.AreEqual("Dogwei", xTypeInfo.GetProperty("private_property_string").GetValue(obj));
/// <summary> /// Рекурсивно обходит дерево объектов и добавляет их в множество objSet /// </summary> /// <param name="xmlObject">текущий xml-объект</param> /// <param name="bIsRoot">Признак корневого объекта в пакете (x-datagram)</param> private void walkThroughXmlObjects(XmlElement xmlObject, bool bIsRoot) { string sParentTypeName; // наименование типа родительского объекта string sParentPropName; // наименование родительского свойства XmlElement xmlProp; XTypeInfo typeInfo = m_xmodel.GetTypeByName(xmlObject.LocalName); if (!typeInfo.IsTemporary) { // если у объекта нет атрибута oid, то установим его, сгенерировав новый гуид if (!xmlObject.HasAttribute("oid")) { xmlObject.SetAttribute("oid", XmlConvert.ToString(Guid.NewGuid())); } if (!bIsRoot) { Debug.Assert(xmlObject.ParentNode != null); Debug.Assert(xmlObject.ParentNode.ParentNode != null); // для вложенного объекта создадим обратное свойство, если его нет, // или проверим, что в нем есть ссылка на родителя, если оно есть. // Массивы и членство в массиве игнорируем. // получим наименование типа родительского объекта sParentTypeName = xmlObject.ParentNode.ParentNode.LocalName; // получим наименование родительского свойства sParentPropName = xmlObject.ParentNode.LocalName; // получим метаданные родительского свойства XPropInfoObject xpropParent = (XPropInfoObject)m_xmodel.GetTypeByName(sParentTypeName).GetProp(sParentPropName); //if (xpropParent != null && xpropParent.Capacity != XPropCapacity.ArrayMembership && xpropParent.Capacity != XPropCapacity.Array) if (xpropParent != null && (xpropParent.Capacity == XPropCapacity.Collection || xpropParent.Capacity == XPropCapacity.CollectionMembership)) { if (xpropParent.ReverseProp != null) { XPropInfoObject xprop = (XPropInfoObject)xpropParent.ReverseProp; // обратное свойство есть - поищем его в текущем объекте xmlProp = (XmlElement)xmlObject.SelectSingleNode(xpropParent.ReverseProp.Name); if (xmlProp == null) { // не нашли - надо создать и поместить туда заглушку родительского объекта xmlProp = xmlObject.OwnerDocument.CreateElement(xprop.Name); xmlProp.AppendChild(XStorageUtils.CreateStubFromObject((XmlElement)xmlObject.ParentNode.ParentNode)); xmlObject.AppendChild(xmlProp); } else if (xmlProp.GetAttribute("loaded").Length > 0 || !xmlProp.HasChildNodes && xmlObject.HasAttribute("new")) { // нашли, но оно помеченно как непрогруженное или пустое нового объекта - удалим его xmlProp.ParentNode.RemoveChild(xmlProp); } else if (!xmlProp.HasChildNodes) { // нашли, но пустое - добавим заглушку родительского объекта xmlProp.AppendChild(XStorageUtils.CreateStubFromObject((XmlElement)xmlObject.ParentNode.ParentNode)); xmlObject.AppendChild(xmlProp); } else { // нашли обратное свойство и оно не пустое- проверим, что в нем есть ссылка на родительский объект // если ссылки нет, то добавим ее string sParentObjectID = xmlObject.ParentNode.ParentNode.Attributes["oid"].Value; if (xmlProp.SelectSingleNode(String.Format("{0}[@oid='{1}']", sParentTypeName, sParentObjectID)) == null) { xmlProp.AppendChild(XStorageUtils.CreateStubFromObject((XmlElement)xmlObject.ParentNode.ParentNode)); } } // пометим свойство специальным атрибутом влияющим на процедуру слияния копий объекта xmlProp.SetAttribute(XObject.MERGE_ACTION_WEAK, "1"); } } } Add(xmlObject, typeInfo); } // по всем объектам (не заглушкам!) в объектных свойствах переданного xml-объекта foreach (XmlElement xmlChildObject in xmlObject.SelectNodes("*/*[*]")) { walkThroughXmlObjects(xmlChildObject, false); } }
public static XStorageObjectBase CreateXStorageObject(XmlElement xmlObject, XTypeInfo typeInfo) { XStorageObjectBase xobj; Guid oid = new Guid(xmlObject.GetAttribute("oid")); Int64 nTS; if (xmlObject.HasAttribute("ts")) { nTS = Int32.Parse(xmlObject.GetAttribute("ts")); } else { nTS = -1; } bool bIsNew = false; if (xmlObject.HasAttribute("delete")) { xobj = new XStorageObjectToDelete(typeInfo, oid, nTS, true); } else { bIsNew = xmlObject.HasAttribute("new"); xobj = new XStorageObjectToSave(typeInfo, oid, nTS, bIsNew); } bool bNeedTrackUniqueIndexParticipation = typeInfo.HasUniqueIndexes && typeInfo.DeferrableIndexes && xobj is XStorageObjectToSave; // по всем свойствам без признака loaded="0" foreach (XmlElement xmlProp in xmlObject.SelectNodes("*[not(@loaded)]")) { XPropInfoBase xprop = typeInfo.GetProp(xmlProp.LocalName); if (xprop == null) { continue; } // если на xml-свойстве неудаляемого объекта есть атрибут с идентификатором цепочки кусочных данных, то занесем его в специальный словарь if (xobj is XStorageObjectToSave && xmlProp.HasAttribute(ATTR_CHUNCK_CHAIN_ID)) { ((XStorageObjectToSave)xobj).PropertiesWithChunkedData.Add(xprop.Name, new Guid(xmlProp.GetAttribute(ATTR_CHUNCK_CHAIN_ID))); } // членство в массиве проигнорируем if (xprop is XPropInfoObjectArray) { if (((XPropInfoObjectArray)xprop).Capacity == XPropCapacity.ArrayMembership) { continue; } } // пустые массивные свойства новых объектов проигнорируем if (bIsNew) { if (xprop is XPropInfoObjectArray || xprop is XPropInfoObjectLink) { if (!xmlProp.HasChildNodes) { continue; } } } xobj.Props.Add(xprop.Name, getPropValue(xmlProp, xprop)); // если свойство участвует в уникальном индексе, запомним это if (bNeedTrackUniqueIndexParticipation) { if (typeInfo.IsPropIncludedIntoUniqueIndex(xprop.Name)) { ((XStorageObjectToSave)xobj).ParticipateInUniqueIndex = true; } } } return(xobj); }
private DomainObjectData DeserializeObject(XmlElement xmlObject, XTypeInfo typeInfo, DomainObjectDataSet dataSet) { DomainObjectData xobj; Guid oid = new Guid(xmlObject.GetAttribute("oid")); bool bIsNew = xmlObject.HasAttribute("new"); bool bToDelete = xmlObject.HasAttribute("delete"); bool bNeedMerge = false; object vPropValue; xobj = dataSet.Find(typeInfo.Name, oid); if (xobj == null) { // такого объекта нет в множестве: создадим его и добавить if (bToDelete) { xobj = dataSet.CreateToDelete(typeInfo.Name, oid); } else { bIsNew = xmlObject.HasAttribute("new"); xobj = dataSet.CreateStub(typeInfo.Name, oid, bIsNew); } } else { // объект уже присутствует if (bIsNew != xobj.IsNew) { throw new XMergeConflictException("Объект " + xobj.TypeInfo.Name + " [" + xobj.ObjectID + "] присутствует в нескольких несогласованных экземплярах: один помечен new='1', а другой нет "); } if (bToDelete != xobj.ToDelete) { throw new XMergeConflictException("Объект " + xobj.TypeInfo.Name + " [" + xobj.ObjectID + "] присутствует в нескольких несогласованных экземплярах: один помечен delete='1', а другой нет "); } bNeedMerge = true; } if (xmlObject.HasAttribute("ts")) { xobj.SetTS(Int64.Parse(xmlObject.GetAttribute("ts"))); } // по всем свойствам без признака loaded="0" foreach (XmlElement xmlProp in xmlObject.SelectNodes("*[not(@loaded)]")) { XPropInfoBase propInfo = typeInfo.GetProp(xmlProp.LocalName); // xml-узлы не соответствующие свойствам из МД игнорируем if (propInfo == null) { continue; } if (!bToDelete && xmlProp.HasAttribute(XDatagram.ATTR_CHUNCK_CHAIN_ID)) { xobj.PropertiesWithChunkedData.Add(propInfo.Name, new Guid(xmlProp.GetAttribute(XDatagram.ATTR_CHUNCK_CHAIN_ID))); } // членство в массиве проигнорируем if (propInfo is XPropInfoObjectArray) { if (((XPropInfoObjectArray)propInfo).Capacity == XPropCapacity.ArrayMembership) { continue; } } // пустые массивные свойства новых объектов проигнорируем if (bIsNew) { if (propInfo is XPropInfoObjectArray || propInfo is XPropInfoObjectLink) { if (!xmlProp.HasChildNodes) { continue; } } } vPropValue = getPropValue(xmlProp, propInfo); if (bNeedMerge && xobj.HasUpdatedProp(propInfo.Name)) { bool bNeedScalarCheck = true; object vPropValueExist = xobj.GetUpdatedPropValue(propInfo.Name); if (propInfo is XPropInfoObject && !(propInfo is XPropInfoObjectScalar)) { // объектное массивное свойство bNeedScalarCheck = false; XPropCapacity capacity = ((XPropInfoObject)propInfo).Capacity; Guid[] valuesOld = (Guid[])vPropValueExist; Guid[] valuesCur = (Guid[])vPropValue; if (capacity == XPropCapacity.Array || (capacity == XPropCapacity.Link && ((XPropInfoObjectLink)propInfo).OrderByProp != null)) { // массивы и упорядоченные линки не подвергаются слиянию - только проверке на совпадение значений if (valuesOld.Length != valuesCur.Length) { throw new XMergeConflictException("Не совпадает количество элементов в свойстве " + propInfo.Name); } for (int i = 0; i < valuesOld.Length; ++i) { if (valuesOld[i] != valuesCur[i]) { throw new XMergeConflictException("Не совпадает значение свойства " + propInfo.Name); } } } else { // коллекция и членство в коллекции - произведем слияние ArrayList aValuesNew = new ArrayList(valuesOld.Length + valuesCur.Length); aValuesNew.AddRange(valuesOld); foreach (Guid value in valuesCur) { if (aValuesNew.IndexOf(value) < 0) { aValuesNew.Add(value); } } Guid[] valuesNew = new Guid[aValuesNew.Count]; aValuesNew.CopyTo(valuesNew); vPropValue = valuesNew; } } else if (propInfo is XPropInfoNumeric) { // числовое свойтсво - будем сравнивать значения, если это не индексное свойство линка if (((XPropInfoNumeric)propInfo).OrderedLinkProp != null) { bNeedScalarCheck = false; } } if (bNeedScalarCheck) { // надо сравнить значения скалярного свойства // т.к. Equals - виртуальный метод, то должно работать if (!vPropValueExist.Equals(vPropValue)) { throw new XMergeConflictException("Значения свойства " + propInfo.Name + " не совпадают"); } } } xobj.SetUpdatedPropValue(propInfo.Name, vPropValue); // Удалено: кусочная загрузка (xmlProp.HasAttribute(ATTR_CHUNCK_CHAIN_ID)) } return(xobj); }
internal DomainObject(UnitOfWork uow, XTypeInfo typeInfo, Guid objectID, DomainObjectState state) : base(typeInfo, objectID) { m_UoW = uow; m_state = state; }
/// <summary> /// Возвращает текст скрипта создания временной таблицы для insert'ов. /// При первом (для типа) обращении вызывает createTempTableCreationScript и кеширует результат. /// Наименование временной таблицы {sTempTableName} /// </summary> /// <param name="xs">Реализация XStorageConnection</param> /// <param name="sTempTableName">Наименование временной таблицы</param> /// <param name="xtype">метаданные типа</param> /// <returns>текст скрипта</returns> protected override string getTempTableCreationScript(XStorageConnection xs, string sTempTableName, XTypeInfo xtype) { return("CREATE TABLE " + sTempTableName + "(" + cacheTempTableCreationScripts.GetValue(xtype, dlgCreateTempTableCreationScript, xs) + ")"); }
public DomainObjectFactory(XTypeInfo xtypeInfo, Type type) : this(xtypeInfo) { m_type = type; }
protected XTypeInfo m_xtypeInfo; // Описание типа ds-объекта. public DomainObjectFactory(XTypeInfo xtypeInfo) { m_xtypeInfo = xtypeInfo; }
public XStorageObjectToDelete(XTypeInfo typeInfo, Guid oid, Int64 ts, bool bIsRoot) : base(typeInfo, oid, ts) { m_bIsRoot = bIsRoot; m_state = XStorageObjectState.ToDelete; }
protected XStorageObjectBase(XTypeInfo typeInfo, Guid oid, Int64 ts) : base(typeInfo, oid, ts) { }