/// <summary>
 /// Возвращает список подстанций РЭС
 /// </summary>
 /// <param name="resId">ИД РЭС</param>
 /// <returns>Список подстанций РЭС</returns>
 public ICollection <Model.Substation> GetSubstations(int resId)
 {
     using (var command = new FbCommand(String.Format("SELECT * FROM PST WHERE ID_RES={0} ORDER BY NAME", resId), fbConnection))
     {
         ICollection <Model.Substation> psts = new List <Model.Substation>();
         try
         {
             if (fbConnection.State == System.Data.ConnectionState.Closed)
             {
                 fbConnection.Open();
             }
             FbDataReader reader = command.ExecuteReader();
             if (reader.HasRows)
             {
                 try
                 {
                     while (reader.Read())
                     {
                         Model.Substation pst = new Model.Substation(reader);
                         pst.Fiders = this.GetFiders(pst.ID);
                         psts.Add(pst);
                     }
                 }
                 finally { reader.Close(); }
             }
             return(psts);
         }
         catch (Exception ex)
         {
             HasError      = true;
             LastException = ex;
             return(null);
         }
     }
 }
        private FiderGraph GetSubstationGraph(TMP.DWRES.Objects.Substation substation)
        {
            // получаем схему подстанции
            _graphScheme = _dwh.GetSubstationLines(substation);

            // строим граф подстанции
            return(MakeGraph(_graphScheme.GraphVertities, _graphScheme.GraphEdges));
        }
        private void BuildSubstationGraph()
        {
            if (SelectedSubstation == null)
            {
                return;
            }

            Model.Substation selectedPst = SelectedSubstation;

            SelectedFider = null;

            MainWindow.Cursor = Cursors.Wait;
            State             = StateType.Building;

            ThreadStart threadStart = delegate()
            {
                try
                {
                    TMP.DWRES.Graph.FiderGraph substationGraph = GetSubstationGraph(selectedPst);
                    ModelGraph = substationGraph;
                }
                finally
                {
                    System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
                    {
                        // получаем участки
                        LinesWithNames = Lines;

                        // сохраняем список тп
                        BuildTPList();

                        MainWindow.Cursor = Cursors.Arrow;
                        State             = StateType.Ready;

                        _currentGraphVariant = GraphVariant.Substation;
                    }));
                }
            };

            Thread thread = new Thread(threadStart);

            thread.Name     = "Build substation graph";
            thread.Priority = ThreadPriority.BelowNormal;
            thread.Start();
        }
        /// <summary>
        /// Возвращает список участков схемы фидеров всей подстанции
        /// </summary>
        /// <param name="substation">Подстанция</param>
        /// <returns>Список участков схемы, список вершин графа схемы</returns>
        public FiderScheme GetSubstationLines(Model.Substation substation)
        {
            FiderScheme result = new FiderScheme();

            string query;

            int id_substation = substation.ID;

            // словарь вершин ИД вершин
            List <Model.LineVertex> substationFidersLinesVertities = new List <Model.LineVertex>();
            // список вершин графа
            List <Graph.FiderGraphVertex> substationFidersVertitiesList = new List <Graph.FiderGraphVertex>();
            // словарь вершин графа
            Dictionary <int, Graph.FiderGraphVertex> substationFidersVertities = new Dictionary <int, Graph.FiderGraphVertex>();
            // список ребер графа
            List <Graph.FiderGraphEdge> substationFidersEdges = new List <Graph.FiderGraphEdge>();

            // общий список участков
            List <Model.Line> substationFidersLineNodesList = new List <Model.Line>();



            // счётчик ИД ребер графа
            int edgeIndex = 1;

            // для каждого фидера подстанции
            foreach (TMP.DWRES.Objects.Fider fider in substation.Fiders)
            {
                // получение списка вершин
                ICollection <Model.LineVertex> currentFiderLinesVertities = GetLinesVertities(fider.ID);

                List <Graph.FiderGraphVertex> currentFiderVertitiesList = new List <Graph.FiderGraphVertex>(currentFiderLinesVertities.Count);

                // заполняем словарь вершин
                foreach (Model.LineVertex item in currentFiderLinesVertities)
                {
                    // создание вершины графа
                    Graph.FiderGraphVertex vertex = new Graph.FiderGraphVertex(item.ID);
                    currentFiderVertitiesList.Add(vertex);
                    // словарь вершин графа с ключём - кодом вершины
                    if (substationFidersVertities.ContainsKey(item.ID) == false)
                    {
                        substationFidersVertities.Add(item.ID, vertex);
                    }
                }

                // вершины графа трёх типов: центр питания (ЦП) или узел подстанции, просто узел и узел, представляющий подстанцию
                // полученные выше списки не содержат наименования узла, для его получения создаём следующие таблицы

                #region Таблица для поиска названия узла ТП по его ИД

                Dictionary <int, string> dictionaryNodeTPNames = new Dictionary <int, string>();
                query = String.Format(
                    @"SELECT NODELINKS.ID, CAST((TP.NAME||'/'||SECTTP.NAME) AS CHAR(100)) NODE_NAME
                      FROM TP
                      INNER JOIN SECTTP
                      ON (SECTTP.ID_PST = TP.ID)
                      INNER JOIN NODELINKS
                      ON (SECTTP.ID_NODELINKS = NODELINKS.ID)
                      WHERE NODELINKS.NODE_TYPE=1", fider.ID);
                try
                {
                    using (var command = new FbCommand(query, fbConnection))
                    {
                        if (fbConnection.State == System.Data.ConnectionState.Closed)
                        {
                            fbConnection.Open();
                        }
                        FbDataReader reader = command.ExecuteReader();
                        if (reader.HasRows)
                        {
                            try
                            {
                                while (reader.Read())
                                {
                                    int    key   = reader[0] != DBNull.Value ? (int)reader[0] : default(int);
                                    string value = reader[1] != DBNull.Value ? (string)reader[1] : default(string);

                                    dictionaryNodeTPNames.Add(key, value);
                                }
                            }
                            finally { reader.Close(); }
                        }
                    }
                }
                catch (Exception ex)
                {
                    HasError      = true;
                    LastException = ex;
                    return(result);
                }

                #endregion Таблица для поиска названия узла ТП по его ИД

                #region Таблица для поиска названия узла по его ИД

                Dictionary <int, string> dictionaryNodeNames = new Dictionary <int, string>();
                query = String.Format(
                    @"SELECT NODELINKS.ID, NODE.NAME NODE_NAME
                      FROM NODE
                      INNER JOIN NODELINKS
                      ON (NODE.ID_NODELINKS = NODELINKS.ID)
                      WHERE NODELINKS.NODE_TYPE=2 AND NODELINKS.ID IN
                      (
                        SELECT LINE.ID_NODE1 NODEID FROM LINE
                        WHERE LINE.ID_FIDER = {0}
                        UNION
                        SELECT LINE.ID_NODE2 NODEID FROM LINE
                        WHERE LINE.ID_FIDER = {0}
                      )", fider.ID);
                try
                {
                    using (var command = new FbCommand(query, fbConnection))
                    {
                        if (fbConnection.State == System.Data.ConnectionState.Closed)
                        {
                            fbConnection.Open();
                        }
                        FbDataReader reader = command.ExecuteReader();
                        if (reader.HasRows)
                        {
                            try
                            {
                                while (reader.Read())
                                {
                                    int    key   = reader[0] != DBNull.Value ? (int)reader[0] : default(int);
                                    string value = reader[1] != DBNull.Value ? (string)reader[1] : default(string);

                                    if (dictionaryNodeNames.ContainsKey(key) == false)
                                    {
                                        dictionaryNodeNames.Add(key, value);
                                    }
                                }
                            }
                            finally { reader.Close(); }
                        }
                    }
                }
                catch (Exception ex)
                {
                    HasError      = true;
                    LastException = ex;
                    return(result);
                }
                #endregion Таблица для поиска названия узла по его ИД

                #region Таблица для поиска названия узла подстанции по его ИД

                Dictionary <int, string> dictionaryNodePSTName = new Dictionary <int, string>();
                query = String.Format(
                    @"SELECT NODELINKS.ID, CAST(('[ЦП] - '||PST.NAME||'/'||SECTPST.NAME) AS CHAR(100)) NODE_NAME
                      FROM PST
                      INNER JOIN SECTPST
                      ON  (SECTPST.ID_PST = PST.ID)
                      INNER JOIN NODELINKS
                      ON  (SECTPST.ID_NODELINKS = NODELINKS.ID)
                      WHERE NODELINKS.NODE_TYPE=3 AND SECTPST.ID = {0}", fider.ID_Sect_NN);
                try
                {
                    using (var command = new FbCommand(query, fbConnection))
                    {
                        if (fbConnection.State == System.Data.ConnectionState.Closed)
                        {
                            fbConnection.Open();
                        }
                        FbDataReader reader = command.ExecuteReader();
                        if (reader.HasRows)
                        {
                            try
                            {
                                while (reader.Read())
                                {
                                    int    key   = reader[0] != DBNull.Value ? (int)reader[0] : default(int);
                                    string value = reader[1] != DBNull.Value ? (string)reader[1] : default(string);

                                    dictionaryNodePSTName.Add(key, value);
                                }
                            }
                            finally { reader.Close(); }
                        }
                    }
                }
                catch (Exception ex)
                {
                    HasError      = true;
                    LastException = ex;
                    return(result);
                }
                #endregion Таблица для поиска названия узла подстанции по его ИД

                // список участков схемы фидера (узел задан ИД)
                ICollection <Model.Line> lineNodesList = GetLines(fider.ID);
                // цикл по всем участкам схемы фидера
                foreach (var item in lineNodesList)
                {
                    FillVertexProperties(item.NodeStartId, ref dictionaryNodeTPNames, ref dictionaryNodeNames, ref dictionaryNodePSTName, ref substationFidersVertities);
                    FillVertexProperties(item.NodeEndId, ref dictionaryNodeTPNames, ref dictionaryNodeNames, ref dictionaryNodePSTName, ref substationFidersVertities);

                    item.NodeStart = substationFidersVertities[item.NodeStartId].Name;
                    item.NodeEnd   = substationFidersVertities[item.NodeEndId].Name;

                    // добавление ребра графа
                    substationFidersEdges.Add(new Graph.FiderGraphEdge(edgeIndex, substationFidersVertities[item.NodeStartId], substationFidersVertities[item.NodeEndId]));
                    edgeIndex++;
                }

                // добавление в общий список
                substationFidersLineNodesList.AddRange(lineNodesList);
                substationFidersVertitiesList.AddRange(currentFiderVertitiesList);
            }

            result.Lines          = substationFidersLineNodesList;
            result.GraphVertities = substationFidersVertitiesList;
            result.GraphEdges     = substationFidersEdges;

            return(result);
        }