public void ReadXml(XmlReader r)
        {
            SortedDictionary<string, SqlDbType> types = null;
              FData.Clear();

              while (r.Read())
              {
            if (r.NodeType != XmlNodeType.Element) continue;

            // Схема параметров
            if (r.Name == "xsd:schema")
              types = ReadXmlSchema(r);
            // Информация о подготовленных параметрах
            else if (r.Name == "Options")
            {
              while (r.Read())
            if (r.Name == "Options" && r.NodeType == XmlNodeType.EndElement) break;
            else if (r.Name == "Prepared")
            {
              if (FPreparedData == null) FPreparedData = new SortedList<Int32, TPreparedDataItem>();
              TPreparedDataItem prepared = new TPreparedDataItem();

              if (r.GetAttribute("Calculated") != null)
              {
                foreach (String str in r.GetAttribute("Calculated").Split(',')) prepared.CalculatedParams.Add(str);
                if (prepared.CalculatedParams.Count == 0) prepared.CalculatedParams = null;
              }

              if (r.GetAttribute("Depended") != null)
              {
                foreach (String str in r.GetAttribute("Depended").Split(',')) prepared.DependedParams.Add(str);
                if (prepared.DependedParams.Count == 0) prepared.DependedParams = null;
              }
              FPreparedData.Add(Int32.Parse(r.GetAttribute("ObjectId")), prepared);
            }
            }
            // Параметры
            else
              ReadXmlValues(r, types);

              }

              // Проверка целостности параметров
              if (FData != null)
            foreach (KeyValuePair<string, Object> LDataPair in FData)
              if (LDataPair.Key[0] == '=' && !IsCalculatedParams(LDataPair.Key))
            throw new Exception(String.Format("Неверное имя параметра '{0}', параметр начинающийся с '=' может быть задан(изменен) только в функции подготовки параметров", LDataPair.Key));
        }
        /// <summary>
        /// Подготавливает параметры
        /// </summary>
        /// <param name="name">Имя функции, для которой необходимо подготовить параметры</param>
        protected void Prepare(String AName)
        {
            InitContextConnection();

              // Получем имя функции для подготовки параметров
              String  LFuncName;
              Int32   LObjectId = GetExtendedProperty(AName, "Prepare", out LFuncName);

              // Если для функции параметры уже подготовленны, то выходим
              if (Prepared(LObjectId)) return;

              // Добавляем признак подготовленности параметров
              if (FPreparedData == null) FPreparedData = new SortedList<Int32, TPreparedDataItem>();
              TPreparedDataItem LPreparedDataItem = new TPreparedDataItem();
              FPreparedData.Add(LObjectId, LPreparedDataItem);
              if (LFuncName == null) return;

              // Добавляем объект в стек подготовки параметров
              if (FPreparedObjects == null) FPreparedObjects = new List<Int32>();
              FPreparedObjects.Add(LObjectId);

              // Выполняем функцию подготовки параметров
              TParams LResult = ExecSQLFunction(LFuncName);

              if (LResult != null)
              {
            // Добавляем подготовленные объекты и зависимые параметры
            if (LResult.FPreparedData != null)
              foreach (KeyValuePair<Int32, TPreparedDataItem> LResultPreparedDataPair in LResult.FPreparedData)
              {
            TPreparedDataItem LFindPreparedDataItem;
            if (FPreparedData.TryGetValue(LResultPreparedDataPair.Key, out LFindPreparedDataItem))
              LFindPreparedDataItem.DependedParams = LResultPreparedDataPair.Value.DependedParams;
            else
              FPreparedData.Add(LResultPreparedDataPair.Key, LResultPreparedDataPair.Value);
              }

            // Добавляем новые параметры
            if (LResult.FData != null)
              foreach (KeyValuePair<String, Object> LDataPair in LResult.FData)
            if (!FData.ContainsKey(LDataPair.Key))
            {
              AddParam(LDataPair.Key, LDataPair.Value);
              if (LPreparedDataItem.CalculatedParams == null)
                LPreparedDataItem.CalculatedParams = new List<String>();
              LPreparedDataItem.CalculatedParams.Add(LDataPair.Key.ToUpper());
            }
              }

              // Удаляем объект из стека подготовки параметров
              FPreparedObjects.RemoveAt(FPreparedObjects.Count - 1);
              if (FPreparedObjects.Count == 0)
              {
            FPreparedObjects          = null;
            FRegisteredDependedParams = null;
              }
        }
        public void Read(System.IO.BinaryReader r)
        {
            // Инфа по параметрам
              if (!ReadValues(r)) return;

              //System.IO.Stream s = r.BaseStream;
              //if(s.Length < s.Position) return;

              // Информация о подготовленных параметрах
              if(r.BaseStream.Position == r.BaseStream.Length) return;

              Int32 count;
              count = Sql.Read7BitEncodedInt(r);

              if (count == 0)
              {
            FPreparedData = null;
              }
              else
              {
            FPreparedData = new SortedList<Int32, TPreparedDataItem>();
            for (Int32 i = 0; i < count; i++)
            {
              Int32 ObjectId = r.ReadInt32();
              TPreparedDataItem prepared = new TPreparedDataItem();

              Int32 count1 = Sql.Read7BitEncodedInt(r);
              if (count1 > 0)
              {
            for (Int32 j = 0; j < count1; j++)
            {
              prepared.DependedParams.Add(r.ReadString());
            }
              }

              count1 = Sql.Read7BitEncodedInt(r);
              if (count1 > 0)
              {
            for (Int32 j = 0; j < count1; j++)
            {
              prepared.CalculatedParams.Add(r.ReadString());
            }
              }

              FPreparedData.Add(ObjectId, prepared);
            }
              }

              // Информация об объектах, для которых происходит подготовка параметров
              if(r.BaseStream.Position == r.BaseStream.Length) return;
              count = Sql.Read7BitEncodedInt(r);

              if (count == 0)
              {
            FPreparedObjects = null;
              }
              else
              {
            FPreparedObjects = new List<Int32>();
            for (Int32 j = 0; j < count; j++)
            {
              FPreparedObjects.Add(r.ReadInt32());
            }
              }

              // Зависимые параметры
              if(r.BaseStream.Position == r.BaseStream.Length) return;
              count = Sql.Read7BitEncodedInt(r);

              if (count == 0)
              {
            FRegisteredDependedParams = null;
              }
              else
              {
            FRegisteredDependedParams = new List<String>();
            for (Int32 j = 0; j < count; j++)
            {
              FRegisteredDependedParams.Add(r.ReadString());
            }
              }

              // На будущее
              //r.ReadInt32();
        }
        /// <summary>
        /// Подготавливает параметры
        /// </summary>
        /// <param name="name">Имя функции, для которой необходимо подготовить параметры</param>
        public void Prepare(SqlString name)
        {
            SqlConnection connection = new SqlConnection("context connection=true");
            connection.Open();

            // Получем имя функции для подготовки параметров
            String funcName;
            Int32 objectId = GetExtendedProperty(connection, name.Value, "Prepare", out funcName);

            // Если для функции параметры уже подготовленны, то выходим
            if (Prepared(objectId)) return;

            // Добавляем признак подготовленности параметров
            if (FPreparedData == null) FPreparedData = new SortedList<Int32, TPreparedDataItem>();
            TPreparedDataItem prepared = new TPreparedDataItem();
            FPreparedData.Add(objectId, prepared);
            if (funcName == null) return;

            // Добавляем объект в стек подготовки параметров
            if (FPreparedObjects == null) FPreparedObjects = new List<Int32>();
            FPreparedObjects.Add(objectId);

            // Выполняем функцию подготовки параметров
            TParams_EMPTY result = ExecSQLFunction(connection, funcName);

            if (result != null)
            {
                // Добавляем подготовленные объекты и зависимые параметры
                foreach (KeyValuePair<Int32, TPreparedDataItem> resultPrepared in result.FPreparedData)
                {
                    if (FPreparedData.ContainsKey(resultPrepared.Key))
                        FPreparedData[resultPrepared.Key].DependedParams = resultPrepared.Value.DependedParams;
                    else
                        FPreparedData.Add(resultPrepared.Key, resultPrepared.Value);
                }

                // Добавляем новые параметры
                foreach (KeyValuePair<String, Object> param in result.FData)
                {
                    if (!FData.ContainsKey(param.Key))
                    {
                        AddParam(param.Key, param.Value);
                        if (prepared.CalculatedParams == null)
                            prepared.CalculatedParams = new List<String>();
                        prepared.CalculatedParams.Add(param.Key.ToUpper());
                    }
                }
            }

            // Удаляем объект из стека подготовки параметров
            FPreparedObjects.RemoveAt(FPreparedObjects.Count - 1);
            if (FPreparedObjects.Count == 0)
            {
                FPreparedObjects = null;
                FRegisteredDependedParams = null;
            }
        }