Ejemplo n.º 1
0
        public void AddDataObjectTest()
        {
            DataObjectCache target = new DataObjectCache(); // TODO: Initialize to an appropriate value
            DataObject      dobj   = null;                  // TODO: Initialize to an appropriate value

            target.AddDataObject(dobj);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Извлечение мастера из сериализованного представления
        /// </summary>
        /// <param name="masternode"> Текущий элемент xml </param>
        /// <param name="dataObject"> Текущий объект данных </param>
        /// <param name="assemblies"> Необходимые сборки </param>
        /// <param name="DataObjectCache"> DataObjectCache </param>
        /// <param name="deserializedObjectsList"> Словарь десериализованных объектов с их первичными ключами </param>
        private static void prv_ReadMaster(
            XmlNode masternode,
            ICSSoft.STORMNET.DataObject dataObject,
            SortedList assemblies,
            DataObjectCache DataObjectCache,
            Dictionary <string, ICSSoft.STORMNET.DataObject> deserializedObjectsList)
        {
            XmlNode    specialTypeNode = masternode.Attributes.GetNamedItem("__Type");
            string     skey            = masternode.Attributes.GetNamedItem("__PrimaryKey").Value;
            DataObject masterobject    = null;

            if (deserializedObjectsList.ContainsKey(skey))
            {
                masterobject = deserializedObjectsList[skey];
            }
            else
            {
                string   stype      = specialTypeNode != null ? specialTypeNode.Value : masternode.Attributes.GetNamedItem("Type").Value;
                string   asmName    = (string)assemblies[stype];
                Assembly asm        = AssemblyLoader.LoadAssembly(asmName);
                Type     mastertype = asm.GetType(stype);
                masterobject = DataObjectCache.CreateDataObject(mastertype, Information.TranslateValueToPrimaryKeyType(mastertype, skey));
                if (specialTypeNode != null)
                { // То есть это был особым образом сериализованный мастер
                    prv_XmlElement2DataObject(
                        (XmlElement)masternode, masterobject, assemblies, DataObjectCache, deserializedObjectsList);
                }
            }

            Information.SetPropValueByName(dataObject, masternode.Name, masterobject);
        }
Ejemplo n.º 3
0
        public void StartCachingTest()
        {
            DataObjectCache target          = new DataObjectCache(); // TODO: Initialize to an appropriate value
            bool            ClipParentCache = false;                 // TODO: Initialize to an appropriate value

            target.StartCaching(ClipParentCache);
        }
Ejemplo n.º 4
0
        public void GetLivingDataObjectTest()
        {
            DataObjectCache target           = new DataObjectCache(); // TODO: Initialize to an appropriate value
            Type            typeofdataobject = null;                  // TODO: Initialize to an appropriate value
            object          key      = null;                          // TODO: Initialize to an appropriate value
            DataObject      expected = null;                          // TODO: Initialize to an appropriate value
            DataObject      actual;

            actual = target.GetLivingDataObject(typeofdataobject, key);
            Assert.Equal(expected, actual);
        }
Ejemplo n.º 5
0
 /// <summary>
 ///     Имитация загрузки объекта с транзакцией.
 /// </summary>
 /// <param name="dataObjectView">Представление для загрузки.</param>
 /// <param name="dobject">Объект для загрузки.</param>
 /// <param name="сlearDataObject">Следует ли очистить объект перед загрузкой.</param>
 /// <param name="сheckExistingObject">Проводить проверку существования ссылочных объектов.</param>
 /// <param name="dataObjectCache">Кэш загрузки объектов.</param>
 /// <param name="connection">Соединение для обновления.</param>
 /// <param name="transaction">Транзакция для обновления.</param>
 public override void LoadObjectByExtConn(
     View dataObjectView,
     DataObject dobject,
     bool сlearDataObject,
     bool сheckExistingObject,
     DataObjectCache dataObjectCache,
     IDbConnection connection,
     IDbTransaction transaction)
 {
     SetViewProperties(dobject, dataObjectView, LoadedValue);
     Counter++;
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Извлечение детейла из сериализованного представления
 /// </summary>
 /// <param name="xmldetailobjects"> Текущий элемент xml </param>
 /// <param name="detail"> Текущий список детейлов </param>
 /// <param name="assemblies"> Необходимые сборки </param>
 /// <param name="DataObjectCache"> DataObjectCache </param>
 /// <param name="deserializedObjectsList"> Словарь десериализованных объектов с их первичными ключами </param>
 private static void prv_ReadDetail(
     XmlNodeList xmldetailobjects,
     DetailArray detail,
     SortedList assemblies,
     DataObjectCache DataObjectCache,
     Dictionary <string, ICSSoft.STORMNET.DataObject> deserializedObjectsList)
 {
     for (int j = 0; j < xmldetailobjects.Count; j++)
     {
         XmlNode     xmldetailobject = xmldetailobjects[j];
         Assembly    asm             = AssemblyLoader.LoadAssembly((string)assemblies[xmldetailobject.Name]);
         System.Type dotype          = asm.GetType(xmldetailobject.Name);
         DataObject  detailobject    = DataObjectCache.CreateDataObject(dotype, Information.TranslateValueToPrimaryKeyType(dotype, ((XmlElement)xmldetailobject).GetAttribute("__PrimaryKey")));
         prv_XmlElement2DataObject((XmlElement)xmldetailobject, detailobject, assemblies, DataObjectCache, deserializedObjectsList);
         detail.AddObject(detailobject);
     }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Получение объекта данных из ранее полученного XML документа
        /// </summary>
        /// <param name="dataObject"> Объект данных, в который будем десериализовывать </param>
        /// <param name="xmlDoc"> Сериализованный объект данных </param>
        public static void XMLDocument2DataObject(ref ICSSoft.STORMNET.DataObject dataObject, XmlDocument xmlDoc)
        {
            if (dataObject == null)
            {
                throw new ArgumentNullException("dataObject");
            }

            var dataObjectCache = new DataObjectCache();

            dataObjectCache.StartCaching(false);
            try
            {
                var xmlMainEl = (XmlElement)xmlDoc.FirstChild;

                XmlNode xmlNode = xmlMainEl.SelectSingleNode("Assemblies");
                if (xmlNode != null)
                {
                    XmlNodeList xmlAssemblies = xmlNode.ChildNodes;

                    var assemblies = new SortedList();
                    for (int i = 0; i < xmlAssemblies.Count; i++)
                    {
                        assemblies.Add(xmlAssemblies[i].Name, ((XmlElement)xmlAssemblies[i]).GetAttribute("Assembly"));
                    }

                    var xmlEl = (XmlElement)xmlMainEl.FirstChild;
                    if (xmlEl.Name == "Assemblies")
                    {
                        xmlEl = (XmlElement)xmlMainEl.LastChild;
                    }

                    prv_XmlElement2DataObject(xmlEl, dataObject, assemblies, dataObjectCache, new Dictionary <string, DataObject>());
                }
                else
                {
                    throw new Exception("Не найдено описание подключаемых сборок в сериализованном объекте");
                }
            }
            finally
            {
                dataObjectCache.StopCaching();
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Прочитать свойство объекта (с целью его дальнейшей десериализации)
        /// </summary>
        /// <param name="xmlEl"> Текущий элемент xml </param>
        /// <param name="dataObject"> Текущий объект данных </param>
        /// <param name="propname"> Читаемое свойство объекта </param>
        /// <param name="assemblies"> Необходимые сборки </param>
        /// <param name="DataObjectCache"> DataObjectCache </param>
        /// <param name="deserializedObjectsList"> Словарь десериализованных объектов с их первичными ключами </param>
        private static void prv_ReadProperty(
            XmlElement xmlEl,
            ICSSoft.STORMNET.DataObject dataObject,
            string propname,
            SortedList assemblies,
            DataObjectCache DataObjectCache,
            Dictionary <string, ICSSoft.STORMNET.DataObject> deserializedObjectsList)
        {
            Type proptype = Information.GetPropertyType(dataObject.GetType(), propname);

            if (proptype.IsSubclassOf(typeof(DataObject)))
            { // Значит, мастер
                XmlNode masternode = xmlEl.GetElementsByTagName(propname)[0];
                prv_ReadMaster(masternode, dataObject, assemblies, DataObjectCache, deserializedObjectsList);
            }
            else
            {
                if (proptype.IsSubclassOf(typeof(DetailArray)))
                { // Значит, детейл
                    var     detail     = (DetailArray)Information.GetPropValueByName(dataObject, propname);
                    XmlNode detailnode = xmlEl.GetElementsByTagName(propname)[0];
                    if (detailnode != null)
                    {
                        XmlNodeList xmldetailobjects = detailnode.ChildNodes;
                        if (xmldetailobjects != null)
                        {
                            prv_ReadDetail(xmldetailobjects, detail, assemblies, DataObjectCache, deserializedObjectsList);
                        }
                    }
                }
                else
                { // Значит, это обычный атрибут
                    XmlAttribute attr = xmlEl.GetAttributeNode(propname);
                    if (attr != null)
                    {
                        prv_ReadAttribute(attr, dataObject);
                    }
                }
            }
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Заполнить объект данных.
        /// </summary>
        /// <param name="dobject">Объект данных.</param>
        /// <param name="values">Значения для заполнения.</param>
        /// <param name="storageStruct">Метаданные структуры хранения.</param>
        /// <param name="customizationStruct">Настройка выборки данных.</param>
        /// <param name="typesByKeys">Служебная структура, увязывающая типы мастеров и их ключи.</param>
        /// <param name="advCols">Дополнительные колонки.</param>
        /// <param name="dataObjectCache">Кэш объектов данных.</param>
        /// <param name="securityManager">Менеджер полномочий.</param>
        public static void FillRowSetToDataObject(DataObject dobject, object[] values, StorageStructForView storageStruct, LoadingCustomizationStruct customizationStruct, System.Collections.SortedList typesByKeys, AdvansedColumn[] advCols, DataObjectCache dataObjectCache, ISecurityManager securityManager)
        {
            Type dobjectType = dobject.GetType();

            /* access type */

            if (!securityManager.AccessObjectCheck(dobjectType, tTypeAccess.Full, false))
            {
                securityManager.AccessObjectCheck(dobjectType, tTypeAccess.Read, true);
            }

            /* access type */

            // Заливаем данные в объект данных.
            int customizationStructViewPropertiesLength = customizationStruct.View.Properties.Length;
            int advColsLength = advCols.Length;

            Information.SetPropValueByName(dobject, "__PrimaryKey", values[customizationStructViewPropertiesLength + advColsLength]);

            // 1. создаем структуру мастеров(свойств-объектов данных).
            System.Collections.SortedList assList = new System.Collections.SortedList();
            int index = customizationStructViewPropertiesLength + 1 + advColsLength;

            CreateMastersStruct(dobject, values, ref index, 0, storageStruct.sources, assList, typesByKeys, dataObjectCache);
            assList.Add(storageStruct.sources, new object[] { dobject, 0 });

            // 2. заливаем данные.
            System.Collections.ArrayList properiesValues = new System.Collections.ArrayList();
            StringCollection             allAdvCols      = new StringCollection();

            int masterPosition = index;

            for (int i = 0; i < advColsLength; i++)
            {
                object value = values[i + customizationStructViewPropertiesLength];
                if (value == DBNull.Value)
                {
                    value = null;
                }

                properiesValues.Add(new[] { advCols[i].Name, value, dobject });
                allAdvCols.Add(advCols[i].Name);
                dobject.DynamicProperties.Add(advCols[i].Name, null);
            }

            for (int i = 0; i < customizationStructViewPropertiesLength; i++)
            {
                StorageStructForView.PropStorage prop = storageStruct.props[i];
                if (Information.IsStoredProperty(dobjectType, prop.Name) || prop.Expression != null)
                {
                    if (prop.MastersTypes == null)
                    {
                        object[] tmp = (object[])assList[prop.source];
                        object   value;
                        if (customizationStruct.ColumnsOrder != null && customizationStruct.ColumnsOrder.Length >= customizationStructViewPropertiesLength)
                        {
                            value = values[Array.IndexOf(customizationStruct.ColumnsOrder, prop.Name)];
                        }
                        else
                        {
                            value = values[i];
                        }

                        if (value == DBNull.Value)
                        {
                            value = null;
                        }

                        if (tmp != null)
                        {
                            properiesValues.Add(
                                new[] { prop.simpleName, value, tmp[0] });
                        }
                    }
                    else
                    {
                        object[] tmp = (object[])assList[prop.source];
                        if (tmp != null)
                        {
                            // Ищем позицию.
                            int tmp1 = (int)tmp[1];
                            int curMasterPosition = masterPosition;
                            for (int j = 0; j < tmp1; j++)
                            {
                                curMasterPosition += prop.MastersTypes[j].Length;
                            }

                            int    k     = 0;
                            object value = values[curMasterPosition];
                            if (value == DBNull.Value)
                            {
                                value = null;
                            }

                            while (k < prop.MastersTypes[tmp1].Length - 1 && value == null)
                            {
                                k++;
                                value = values[curMasterPosition + k];
                                if (value == DBNull.Value)
                                {
                                    value = null;
                                }
                            }

                            object tmp0 = tmp[0];
                            if (value != null)
                            {
                                if (Information.GetPropValueByName((DataObject)tmp0, prop.simpleName) == null)
                                {
                                    DataObject no = dataObjectCache.CreateDataObject(prop.MastersTypes[tmp1][k], value);
                                    if (no.GetStatus(false) == ObjectStatus.Created)
                                    {
                                        no.SetStatus(ObjectStatus.UnAltered);
                                        no.SetLoadingState(LoadingState.LightLoaded);
                                        no.InitDataCopy(dataObjectCache);
                                    }

                                    value = no;
                                    properiesValues.Add(new[] { prop.simpleName, value, tmp0 });
                                }
                                else
                                {
                                    // changed by fat
                                    properiesValues.Add(new[] { prop.simpleName, Information.GetPropValueByName((DataObject)tmp0, prop.simpleName), tmp0 });
                                }
                            }
                            else
                            {
                                properiesValues.Add(new[] { prop.simpleName, null, tmp0 });
                            }
                        }

                        masterPosition += prop.MastersTypesCount;
                    }
                }
            }

            // 2.2 Записываем в объекты.
            System.Collections.SortedList curObjProperiesValues = new System.Collections.SortedList();
            while (properiesValues.Count > 0)
            {
                // a. Выбираем для текущего объекта все свойства.
                object[]   tmp    = (object[])properiesValues[0];
                DataObject curobj = (DataObject)tmp[2];
                dobjectType = curobj.GetType();
                curObjProperiesValues.Clear();

                List <string> loadedPropsColl = curobj.GetLoadedPropertiesList();

                for (int i = properiesValues.Count - 1; i >= 0; i--)
                {
                    tmp = (object[])properiesValues[i];
                    if (tmp[2] == curobj)
                    {
                        object tmp0 = tmp[0];
                        if (!curObjProperiesValues.ContainsKey(tmp0))
                        {
                            curObjProperiesValues.Add(tmp0, tmp[1]);
                            if (!loadedPropsColl.Contains((string)tmp0))
                            {
                                loadedPropsColl.Add((string)tmp0);
                            }
                        }

                        properiesValues.RemoveAt(i);
                    }
                }

                // b. Раскидываем согласно LoadOrder;
                string[] loadOrder       = Information.GetLoadingOrder(dobjectType);
                int      loadOrderLength = loadOrder.Length;
                for (int i = 0; i < loadOrderLength; i++)
                {
                    string propName = loadOrder[i];
                    if (curObjProperiesValues.ContainsKey(propName))
                    {
                        Information.SetPropValueByName(curobj, propName, curObjProperiesValues[propName]);
                        curObjProperiesValues.Remove(propName);
                    }
                }

                int curObjPropertiesValuesCount = curObjProperiesValues.Count;
                for (int i = 0; i < curObjPropertiesValuesCount; i++)
                {
                    Information.SetPropValueByName(curobj, (string)curObjProperiesValues.GetKey(i), curObjProperiesValues.GetByIndex(i));
                }

                if (loadedPropsColl.Count >= Information.GetAllPropertyNames(dobjectType).Length)
                {
                    curobj.SetLoadingState(LoadingState.Loaded);
                }
                else
                {
                    curobj.SetLoadingState(LoadingState.LightLoaded);
                    curobj.AddLoadedProperties(loadedPropsColl);
                }

                curobj.SetStatus(ObjectStatus.UnAltered);
            }
        }
Ejemplo n.º 11
0
        public void StopCachingTest()
        {
            DataObjectCache target = new DataObjectCache(); // TODO: Initialize to an appropriate value

            target.StopCaching();
        }
Ejemplo n.º 12
0
        public void DataObjectCacheConstructorTest()
        {
            DataObjectCache target = new DataObjectCache();

            Assert.NotNull(target);
        }
 /// <summary>
 /// Обновить хранилище по объектам. При ошибках делается попытка возобновления транзакции с другого запроса,
 /// т.к. предполагается, что запросы должны быть выполнены в другом порядке.
 /// </summary>
 /// <param name="objects">Объекты данных для обновления.</param>
 /// <param name="DataObjectCache">Кэш объектов данных.</param>
 public virtual void UpdateObjects(ref DataObject[] objects, DataObjectCache DataObjectCache)
 {
     UpdateObjects(ref objects, DataObjectCache, false);
 }
        /// <summary>
        /// Обновить хранилище по объектам (есть параметр, указывающий, всегда ли необходимо взводить ошибку
        /// и откатывать транзакцию при неудачном запросе в базу данных). Если
        /// он true, всегда взводится ошибка. Иначе, выполнение продолжается.
        /// Однако, при этом есть опасность преждевременного окончания транзакции, с переходом для остальных
        /// запросов режима транзакционности в autocommit. Проявлением проблемы являются ошибки навроде:
        /// The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION
        /// </summary>
        /// <param name="objects">Объекты для обновления.</param>
        /// <param name="DataObjectCache">Кэш объектов данных.</param>
        /// <param name="AlwaysThrowException">Если произошла ошибка в базе данных, не пытаться выполнять других запросов, сразу взводить ошибку и откатывать транзакцию.</param>
        public virtual void UpdateObjects(ref DataObject[] objects, DataObjectCache DataObjectCache, bool AlwaysThrowException)
        {
            object id = BusinessTaskMonitor.BeginTask("Update objects");

            if (!DoNotChangeCustomizationString && ChangeCustomizationString != null)
            {
                var tps = new List <Type>();
                foreach (DataObject d in objects)
                {
                    Type t = d.GetType();
                    if (!tps.Contains(t))
                    {
                        tps.Add(t);
                    }
                }

                string cs = ChangeCustomizationString(tps.ToArray());
                customizationString = string.IsNullOrEmpty(cs) ? customizationString : cs;
            }

            // Перенесли этот метод повыше, потому что строка соединения может быть сменена в бизнес-сервере делегатом смены строки соединения (если что-нибудь почитают).
            IDbConnection conection = GetConnection();

            var DeleteQueries      = new StringCollection();
            var UpdateQueries      = new StringCollection();
            var UpdateFirstQueries = new StringCollection();
            var InsertQueries      = new StringCollection();

            var DeleteTables    = new StringCollection();
            var UpdateTables    = new StringCollection();
            var InsertTables    = new StringCollection();
            var TableOperations = new SortedList();
            var QueryOrder      = new StringCollection();

            var AllQueriedObjects = new ArrayList();

            var auditOperationInfoList = new List <AuditAdditionalInfo>();
            var extraProcessingList    = new List <DataObject>();

            GenerateQueriesForUpdateObjects(DeleteQueries, DeleteTables, UpdateQueries, UpdateFirstQueries, UpdateTables, InsertQueries, InsertTables, TableOperations, QueryOrder, true, AllQueriedObjects, DataObjectCache, extraProcessingList, objects);

            GenerateAuditForAggregators(AllQueriedObjects, DataObjectCache, ref extraProcessingList);

            OnBeforeUpdateObjects(AllQueriedObjects);

            Exception ex = null;

            /*access checks*/

            foreach (DataObject dtob in AllQueriedObjects)
            {
                Type dobjType = dtob.GetType();
                if (!SecurityManager.AccessObjectCheck(dobjType, tTypeAccess.Full, false))
                {
                    switch (dtob.GetStatus(false))
                    {
                    case ObjectStatus.Created:
                        SecurityManager.AccessObjectCheck(dobjType, tTypeAccess.Insert, true);
                        break;

                    case ObjectStatus.Altered:
                        SecurityManager.AccessObjectCheck(dobjType, tTypeAccess.Update, true);
                        break;

                    case ObjectStatus.Deleted:
                        SecurityManager.AccessObjectCheck(dobjType, tTypeAccess.Delete, true);
                        break;
                    }
                }
            }

            /*access checks*/

            if (DeleteQueries.Count > 0 || UpdateQueries.Count > 0 || InsertQueries.Count > 0)
            { // Порядок выполнения запросов: delete,insert,update
                if (AuditService.IsAuditEnabled)
                {
                    /* Аудит проводится именно здесь, поскольку на этот момент все бизнес-сервера на объектах уже выполнились,
                     * объекты находятся именно в том состоянии, в каком должны были пойти в базу + в будущем можно транзакцию передать на исполнение
                     */
                    AuditOperation(extraProcessingList, auditOperationInfoList); // TODO: подумать, как записывать аудит до OnBeforeUpdateObjects, но уже потенциально с транзакцией
                }

                conection.Open();
                IDbTransaction trans = null;

                string query       = string.Empty;
                string prevQueries = string.Empty;
                object subTask     = null;
                try
                {
                    trans = CreateTransaction(conection);
                    IDbCommand command = conection.CreateCommand();
                    command.Transaction = trans;

                    #region прошли вглубь обрабатывая only Update||Insert
                    bool go = true;
                    do
                    {
                        string table = QueryOrder[0];
                        if (!TableOperations.ContainsKey(table))
                        {
                            TableOperations.Add(table, OperationType.None);
                        }
                        var ops = (OperationType)TableOperations[table];

                        if ((ops & OperationType.Delete) != OperationType.Delete)
                        {
                            // Смотрим есть ли Инсерты
                            if ((ops & OperationType.Insert) == OperationType.Insert)
                            {
                                if (
                                    (ex =
                                         RunCommands(InsertQueries, InsertTables, table, command, id, AlwaysThrowException))
                                    == null)
                                {
                                    ops = Minus(ops, OperationType.Insert);
                                    TableOperations[table] = ops;
                                }
                                else
                                {
                                    go = false;
                                }
                            }

                            // Смотрим есть ли Update
                            if (go && ((ops & OperationType.Update) == OperationType.Update))
                            {
                                if ((ex = RunCommands(UpdateQueries, UpdateTables, table, command, id, AlwaysThrowException)) == null)
                                {
                                    ops = Minus(ops, OperationType.Update);
                                    TableOperations[table] = ops;
                                }
                                else
                                {
                                    go = false;
                                }
                            }

                            if (go)
                            {
                                QueryOrder.RemoveAt(0);
                                go = QueryOrder.Count > 0;
                            }
                        }
                        else
                        {
                            go = false;
                        }
                    }while (go);

                    #endregion
                    if (QueryOrder.Count > 0)
                    {
                        #region сзади чистые Update

                        go = true;
                        int queryOrderIndex = QueryOrder.Count - 1;
                        do
                        {
                            string table = QueryOrder[queryOrderIndex];
                            if (TableOperations.ContainsKey(table))
                            {
                                var ops = (OperationType)TableOperations[table];

                                if (ops == OperationType.Update)
                                {
                                    if (
                                        (ex = RunCommands(UpdateQueries, UpdateTables, table, command, id, AlwaysThrowException)) == null)
                                    {
                                        ops = Minus(ops, OperationType.Update);
                                        TableOperations[table] = ops;
                                    }
                                    else
                                    {
                                        go = false;
                                    }

                                    if (go)
                                    {
                                        queryOrderIndex--;
                                        go = queryOrderIndex >= 0;
                                    }
                                }
                                else
                                {
                                    go = false;
                                }
                            }
                            else
                            {
                                queryOrderIndex--;
                            }
                        }while (go);

                        #endregion
                    }

                    foreach (string table in QueryOrder)
                    {
                        if ((ex = RunCommands(UpdateFirstQueries, UpdateTables, table, command, id, AlwaysThrowException)) != null)
                        {
                            throw ex;
                        }
                    }

                    // Удаляем в обратном порядке.
                    for (int i = QueryOrder.Count - 1; i >= 0; i--)
                    {
                        string table = QueryOrder[i];
                        if ((ex = RunCommands(DeleteQueries, DeleteTables, table, command, id, AlwaysThrowException)) != null)
                        {
                            throw ex;
                        }
                    }

                    // А теперь опять с начала
                    foreach (string table in QueryOrder)
                    {
                        if ((ex = RunCommands(InsertQueries, InsertTables, table, command, id, AlwaysThrowException)) != null)
                        {
                            throw ex;
                        }

                        if ((ex = RunCommands(UpdateQueries, UpdateTables, table, command, id, AlwaysThrowException)) != null)
                        {
                            throw ex;
                        }
                    }

                    if (AuditService.IsAuditEnabled && auditOperationInfoList.Count > 0)
                    { // Нужно зафиксировать операции аудита (то есть сообщить, что всё было корректно выполнено и запомнить время)
                        AuditService.RatifyAuditOperationWithAutoFields(
                            tExecutionVariant.Executed,
                            AuditAdditionalInfo.SetNewFieldValuesForList(trans, this, auditOperationInfoList),
                            this,
                            true);
                    }

                    if (trans != null)
                    {
                        trans.Commit();
                    }
                }
                catch (Exception excpt)
                {
                    if (trans != null)
                    {
                        trans.Rollback();
                    }
                    if (AuditService.IsAuditEnabled && auditOperationInfoList.Count > 0)
                    { // Нужно зафиксировать операции аудита (то есть сообщить, что всё было откачено)
                        AuditService.RatifyAuditOperationWithAutoFields(tExecutionVariant.Failed, auditOperationInfoList, this, false);
                    }

                    conection.Close();
                    BusinessTaskMonitor.EndSubTask(subTask);
                    throw new ExecutingQueryException(query, prevQueries, excpt);
                }

                conection.Close();

                var res = new ArrayList();
                foreach (DataObject changedObject in objects)
                {
                    changedObject.ClearPrototyping(true);

                    if (changedObject.GetStatus(false) != STORMDO.ObjectStatus.Deleted)
                    {
                        Utils.UpdateInternalDataInObjects(changedObject, true, DataObjectCache);
                        res.Add(changedObject);
                    }
                }

                foreach (DataObject dobj in AllQueriedObjects)
                {
                    if (dobj.GetStatus(false) != STORMDO.ObjectStatus.Deleted &&
                        dobj.GetStatus(false) != STORMDO.ObjectStatus.UnAltered)
                    {
                        Utils.UpdateInternalDataInObjects(dobj, true, DataObjectCache);
                    }
                }

                objects = new DataObject[res.Count];
                res.CopyTo(objects);
                BusinessTaskMonitor.EndTask(id);
            }

            if (AfterUpdateObjects != null)
            {
                AfterUpdateObjects(this, new DataObjectsEventArgs(objects));
            }
        }