ulysseskao
2016-04-29 b0c18d369abd06075c83759b0e19823c2a11d716
CCSTrace/CCS/EventAI/TraceSubject.cs
@@ -1,99 +1,95 @@
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections;
using TRACEROBJECTLib;
using System.Data.OracleClient;
using TRACEROBJECTLib;
namespace CCSTrace.CCS.EventAI
{
    public class TraceSubject
    {
       private String          m_dbConnectionString;
       static bool            IsNewCase;
       static ArrayList       m_LinkList;                        // store the switch of the new case path
        static TraceEngine      m_tEngine;
       static Hashtable      m_TreeMap;                        // store the switch of the old case path
       static int            s_Fsc;
       static int            s_Ufid;
        private RecordLog       _Plogger;
       private ArrayList      m_Tmp = new ArrayList();
        private NetworkContext  m_pContext;
        private string _mDbConnectionString;
        private static bool _isNewCase;
        private static ArrayList _mLinkList;                        // store the switch of the new case path
        private static TraceEngine _mTEngine;
        private static Hashtable _mTreeMap;                             // store the switch of the old case path
        private static int _sFsc;
        private static int _sUfid;
        private readonly RecordLog _plogger;
        private readonly ArrayList _mTmp = new ArrayList();
        private NetworkContext _mPContext;
        private OracleConnection _ConnectionTPC = null;
        private OracleTransaction _Transaction;
        private readonly OracleConnection _connectionTpc;
        private readonly OracleTransaction _transaction;
        public TraceSubject(OracleConnection _Conn, OracleTransaction _Trx, String traceConnectionString, RecordLog _Log)
        public TraceSubject(OracleConnection conn, OracleTransaction trx, string traceConnectionString, RecordLog log)
        {
            _ConnectionTPC = _Conn;
            _Transaction = _Trx;
          _Plogger = _Log;
            m_dbConnectionString = traceConnectionString;
          try
            {
             if (m_tEngine == null) {
                m_tEngine = new TraceEngine();
             }
          }
          catch (Exception ex) {
             _Plogger.Error(ex.Message);
                throw ex;
          }
       }
       public void discardEngine() {
          if (m_tEngine != null) {
             m_tEngine = null;
          }
       }
       public ArrayList getNewResult() {
          return m_LinkList;
       }
       public Hashtable getOldResult() {
          return m_TreeMap;
       }
       // for EOS(only get the reverse tree)
       public void startTrace(int Start_Fsc, int Start_Ufid, bool m_IsNew) {
          s_Fsc = Start_Fsc;
          s_Ufid = Start_Ufid;
          IsNewCase = m_IsNew;
          m_TreeMap = new Hashtable();
          m_LinkList = new ArrayList();
            _connectionTpc = conn;
            _transaction = trx;
            _plogger = log;
            _mDbConnectionString = traceConnectionString;
            try
            {
              this.setReverseTree(Trace(true));
                if (_mTEngine == null)
                {
                    _mTEngine = new TraceEngine();
                }
            }
            catch (Exception e) {
                _Plogger.Error(e.Message);
            catch (Exception ex)
            {
                _plogger.Error(ex.Message);
                throw ex;
            }
        }
        public void DiscardEngine()
        {
            _mTEngine = null;
        }
        public ArrayList GetNewResult()
        {
            return _mLinkList;
        }
        public Hashtable GetOldResult()
        {
            return _mTreeMap;
        }
        // for EOS(only get the reverse tree)
        public void StartTrace(int startFsc, int startUfid, bool mIsNew)
        {
            _sFsc = startFsc;
            _sUfid = startUfid;
            _isNewCase = mIsNew;
            _mTreeMap = new Hashtable();
            _mLinkList = new ArrayList();
            try
            {
                SetReverseTree(Trace(true));
            }
            catch (Exception e)
            {
                _plogger.Error(e.Message);
                Console.WriteLine(e.StackTrace);
                throw e;
            }
       }
        }
       private bool getSwitchOn(int UFID) {
          String SqlStmt;
        private bool GetSwitchOn(int ufid)
        {
            var sqlStmt = "SELECT M.OSTATUS as OSTATUS FROM (SELECT UFID,OSTATUS FROM BASEDB.CONNECTIVITY WHERE FSC = 114) M,"
                             + "BASEDB.SWITCH S WHERE M.UFID = S.UFID AND S.NSTATUS <> 0 AND M.UFID = " + ufid;
          SqlStmt = "SELECT M.OSTATUS as OSTATUS FROM (SELECT UFID,OSTATUS FROM BASEDB.CONNECTIVITY WHERE FSC = 114) M,"
                + "BASEDB.SWITCH S WHERE M.UFID = S.UFID AND S.NSTATUS <> 0 AND M.UFID = " + UFID;
            OracleCommand Command = null;
            OracleCommand command = null;
            OracleDataReader reader = null;
            try
            {
                Command = new OracleCommand(SqlStmt, _ConnectionTPC, _Transaction);
                reader = Command.ExecuteReader();
                command = new OracleCommand(sqlStmt, _connectionTpc, _transaction);
                reader = command.ExecuteReader();
                if (reader.Read())
                {
@@ -104,32 +100,29 @@
            }
            catch (Exception e)
            {
                _Plogger.Error(e.Message);
                _plogger.Error(e.Message);
                Console.WriteLine(e.StackTrace);
            }
            finally
            {
                if (Command != null)
                    Command.Dispose();
                command?.Dispose();
                if (reader != null)
                    reader.Close();
                reader?.Close();
            }
          return false;
       }
            return false;
        }
        private bool getJumperOn(int UFID) {
            String SqlStmt;
        private bool GetJumperOn(int ufid)
        {
            var sqlStmt = "SELECT OSTATUS FROM BASEDB.CONNECTIVITY WHERE FSC = 109 AND UFID = " + ufid;
            SqlStmt = "SELECT OSTATUS FROM BASEDB.CONNECTIVITY WHERE FSC = 109 AND UFID = " + UFID;
            OracleCommand Command = null;
            OracleCommand command = null;
            OracleDataReader reader = null;
            try
            {
                Command = new OracleCommand(SqlStmt, _ConnectionTPC, _Transaction);
                reader = Command.ExecuteReader();
                command = new OracleCommand(sqlStmt, _connectionTpc, _transaction);
                reader = command.ExecuteReader();
                if (reader.Read())
                {
@@ -140,13 +133,13 @@
            }
            catch (Exception e)
            {
                _Plogger.Error(e.Message);
                _plogger.Error(e.Message);
                Console.WriteLine(e.StackTrace);
            }
            finally
            {
                if (Command != null)
                    Command.Dispose();
                if (command != null)
                    command.Dispose();
                if (reader != null)
                    reader.Close();
@@ -154,102 +147,108 @@
            return false;
        }
        private Hashtable TraceCounts = new Hashtable();
        private readonly Hashtable _traceCounts = new Hashtable();
       private void setReverseTree(ResultTree tree) {
          int i = 0;
        private void SetReverseTree(ResultTree tree)
        {
            int i = 0;
            TreeIterator iti = null;
            bool ostatus = true;
          if (tree != null) {
             i = 0;
             iti = tree.CreateTreeIterator();
             bool isNotEnd = true;
            if (tree != null)
            {
                i = 0;
                iti = tree.CreateTreeIterator();
                bool isNotEnd = true;
             while (isNotEnd) {
                    if (getTraceCount(iti.Value.ClassID, iti.Value.ObjectID) > 5)
                while (isNotEnd)
                {
                    if (GetTraceCount(iti.Value.ClassID, iti.Value.ObjectID) > 5)
                        throw new TraceLoopException("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + iti.Value.ClassID + "," + iti.Value.ObjectID + ")");
                    else
                        AddTraceCount(iti.Value.ClassID, iti.Value.ObjectID);
                    while (iti.IsLeaf == 0)
                    {
                   TRACEROBJECTLib.TreeNode node = iti.Value;
                        TreeNode node = iti.Value;
                        if ((node.ClassID == 114) || (node.ClassID == 108) || (node.ClassID == 109))
                        {
                            Equipment Equip = new Equipment(node.ClassID, node.ObjectID);
                            Equipment equip = new Equipment(node.ClassID, node.ObjectID);
                      if (IsNewCase)
                                m_LinkList.Add(Equip);
                      else {
                         m_TreeMap.Add(node.ObjectID, Equip);
                         m_Tmp.Add(Equip);
                      }
                      i++;
/*                            if (getTraceCount(node.ClassID, node.ObjectID) > 2)
                                throw new Exception("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + node.ClassID + "," + node.ObjectID + ")");
                            if (_isNewCase)
                                _mLinkList.Add(equip);
                            else
                                AddTraceCount(node.ClassID, node.ObjectID);
*/                   }
                            {
                                _mTreeMap.Add(node.ObjectID, equip);
                                _mTmp.Add(equip);
                            }
                            i++;
                            /*                            if (getTraceCount(node.ClassID, node.ObjectID) > 2)
                                                            throw new Exception("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + node.ClassID + "," + node.ObjectID + ")");
                                                        else
                                                            AddTraceCount(node.ClassID, node.ObjectID);
                            */
                        }
                        Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
                        _Plogger.Info(node.ClassID + "----->" + node.ObjectID);
                        _plogger.Info(node.ClassID + "----->" + node.ObjectID);
                   iti.MoveDescent((short) 0);
                }
                        iti.MoveDescent((short)0);
                    }
                // 當從breaker出來的導線不只一條時,breaker可能會不被add(因為breaker是leaf但其parent的DescentCount > 1,所以被忽略)
                /*
                 * if ( ((com.origo.TraceModel.ITreeNode)iti.get_Value()).get_ClassID() == EOS.LocalVariable.Breaker ) {
                    // 當從breaker出來的導線不只一條時,breaker可能會不被add(因為breaker是leaf但其parent的DescentCount > 1,所以被忽略)
                    /*
                 * if ( ((com.origo.TraceModel.ITreeNode)iti.get_Value()).get_ClassID() == EOS.GlobalVariable.Breaker ) {
                 * com.origo.TraceModel.ITreeNode node = iti.get_Value(); Equipment Equip = new Equipment(node.get_ClassID(),node.get_ObjectID()); if (
                 * IsNewCase ) m_LinkList.add(i,Equip); else { m_TreeMap.put(new Integer(node.get_ObjectID()),Equip); m_Tmp.add(Equip); }
                 * System.out.println(node.get_ClassID() + "----->" + node.get_ObjectID()); System.out.println("Trace Finish...."); i++; break; }
                 */
                if ((iti.Value).ClassID == CCS.LocalVariable.Breaker) {
                        TRACEROBJECTLib.TreeNode node = iti.Value;
                   Equipment Equip = new Equipment(node.ClassID, node.ObjectID);
                    if ((iti.Value).ClassID == GlobalVariable.Breaker)
                    {
                        TreeNode node = iti.Value;
                        Equipment equip = new Equipment(node.ClassID, node.ObjectID);
                   if (IsNewCase)
                            m_LinkList.Add(Equip);
                   else
                        if (_isNewCase)
                            _mLinkList.Add(equip);
                        else
                        {
                      m_TreeMap.Add(node.ObjectID, Equip);
                      m_Tmp.Add(Equip);
                   }
                            _mTreeMap.Add(node.ObjectID, equip);
                            _mTmp.Add(equip);
                        }
                        i++;    //後面直接就FINISH,所以就不用判斷tracecount
                   Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
                        _Plogger.Info(node.ClassID + "----->" + node.ObjectID);
                   Console.WriteLine("Trace Finish....");
                        _Plogger.Info("Trace Finish....");
                   break;
                }
                // 當追蹤到被切開的開關且該上一層設備只有該開關一個child)
                else if (iti.Value.ClassID == CCS.LocalVariable.Switch || iti.Value.ClassID == CCS.LocalVariable.Jumper ) {
                        TRACEROBJECTLib.TreeNode node = iti.Value;
                   iti.MoveAscent();
                        Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
                        _plogger.Info(node.ClassID + "----->" + node.ObjectID);
                        Console.WriteLine("Trace Finish....");
                        _plogger.Info("Trace Finish....");
                        break;
                    }
                    // 當追蹤到被切開的開關且該上一層設備只有該開關一個child)
                    else if (iti.Value.ClassID == GlobalVariable.Switch || iti.Value.ClassID == GlobalVariable.Jumper)
                    {
                        TreeNode node = iti.Value;
                        iti.MoveAscent();
                    Equipment Equip = new Equipment(node.ClassID, node.ObjectID);
                        Equipment equip = new Equipment(node.ClassID, node.ObjectID);
                        if (isEndEquip(Equip))
                        if (IsEndEquip(equip))
                        {
                            if (IsNewCase)
                                m_LinkList.Add(Equip);
                            if (_isNewCase)
                                _mLinkList.Add(equip);
                            else
                            {
                                m_TreeMap.Add(node.ObjectID, Equip);
                                m_Tmp.Add(Equip);
                                _mTreeMap.Add(node.ObjectID, equip);
                                _mTmp.Add(equip);
                            }
                            i++;    //後面直接就FINISH,所以就不用判斷tracecount
                            Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
                            _Plogger.Info(node.ClassID + "----->" + node.ObjectID);
                            _plogger.Info(node.ClassID + "----->" + node.ObjectID);
                            Console.WriteLine("Trace Finish....");
                            _Plogger.Info("Trace Finish....");
                            _plogger.Info("Trace Finish....");
                            break;
                        }
@@ -280,189 +279,210 @@
                        //    _Plogger.Info("Trace Finish....");
                        //    break;
                        //}
                }
                    }
                    else
                {
                        TRACEROBJECTLib.TreeNode node = iti.Value;
                    {
                        TreeNode node = iti.Value;
                        iti.MoveAscent();
                        if (iti.DescentCount == 1)
                          throw new Exception("追蹤到非開關類斷開之設備(Fsc = " + node.ClassID + ",Ufid = " + node.ObjectID);
                            throw new Exception("追蹤到非開關類斷開之設備(Fsc = " + node.ClassID + ",Ufid = " + node.ObjectID);
                    }
                for (int j = 1; j < iti.DescentCount; j++) {
                   iti.MoveDescent((short) j);
                    for (int j = 1; j < iti.DescentCount; j++)
                    {
                        iti.MoveDescent((short)j);
                   if (iti.IsLeaf == 1) {
                            TRACEROBJECTLib.TreeNode node = iti.Value;
                      Equipment Equip = new Equipment(node.ClassID, node.ObjectID);
                        if (iti.IsLeaf == 1)
                        {
                            TreeNode node = iti.Value;
                            Equipment equip = new Equipment(node.ClassID, node.ObjectID);
                      switch (node.ClassID) {
                      case 108:
                         if (IsNewCase)
                                    m_LinkList.Add(Equip);
                         else
                                {
                            m_TreeMap.Add(node.ObjectID, Equip);
                            m_Tmp.Add(Equip);
                         }
                                Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
                                _Plogger.Info(node.ClassID + "----->" + node.ObjectID);
                                i++;
/*                                if (getTraceCount(node.ClassID, node.ObjectID) > 2)
                                    throw new Exception("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + node.ClassID + "," + node.ObjectID + ")");
                                else
                                    AddTraceCount(node.ClassID, node.ObjectID);
*/
                         break;
                            case 109:
                      case 114:
                              switch (node.ClassID)
                              {
                                case 114:
                                  ostatus = getSwitchOn(node.ObjectID);
                                  break;
                                case 109:
                                  ostatus = getJumperOn(node.ObjectID);
                                  break;
                              }
                         // Only for switch because the breaker only has one node to descent
                         if (!ostatus) {
                            if (IsNewCase)
                                        m_LinkList.Add(Equip);
                            else {
                               m_TreeMap.Add(node.ObjectID, Equip);
                               m_Tmp.Add(Equip);
                            }
                                    Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
                                    _Plogger.Info(node.ClassID + "----->" + node.ObjectID);
                            i++;
/*                                    if (getTraceCount(node.ClassID, node.ObjectID) > 2)
                                        throw new Exception("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + node.ClassID + "," + node.ObjectID + ")");
                            switch (node.ClassID)
                            {
                                case 108:
                                    if (_isNewCase)
                                        _mLinkList.Add(equip);
                                    else
                                        AddTraceCount(node.ClassID, node.ObjectID);
*/
                         }
                         break;
                      default:
                         break;
                      } // switch
                                    {
                                        _mTreeMap.Add(node.ObjectID, equip);
                                        _mTmp.Add(equip);
                                    }
                      iti.MoveAscent();
                      isNotEnd = false;
                   } else {
                      isNotEnd = true;
                      break;
                   }
                } // for
             } // while
             Console.WriteLine("Tree Node Count = " + i);
                _Plogger.Info("Tree Node Count = " + i);
          } else
          {
              Console.WriteLine("Tree is null");
              _Plogger.Info("Tree is null");
              throw new Exception("無法追蹤到任何設備,可能是該用戶所在變壓器設備連結性有問題。");
                                    Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
                                    _plogger.Info(node.ClassID + "----->" + node.ObjectID);
                                    i++;
                                    /*                                if (getTraceCount(node.ClassID, node.ObjectID) > 2)
                                                                        throw new Exception("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + node.ClassID + "," + node.ObjectID + ")");
                                                                    else
                                                                        AddTraceCount(node.ClassID, node.ObjectID);
                                    */
                                    break;
                                case 109:
                                case 114:
                                    switch (node.ClassID)
                                    {
                                        case 114:
                                            ostatus = GetSwitchOn(node.ObjectID);
                                            break;
                                        case 109:
                                            ostatus = GetJumperOn(node.ObjectID);
                                            break;
                                    }
                                    // Only for switch because the breaker only has one node to descent
                                    if (!ostatus)
                                    {
                                        if (_isNewCase)
                                            _mLinkList.Add(equip);
                                        else
                                        {
                                            _mTreeMap.Add(node.ObjectID, equip);
                                            _mTmp.Add(equip);
                                        }
                                        Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
                                        _plogger.Info(node.ClassID + "----->" + node.ObjectID);
                                        i++;
                                        /*                                    if (getTraceCount(node.ClassID, node.ObjectID) > 2)
                                                                                throw new Exception("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + node.ClassID + "," + node.ObjectID + ")");
                                                                            else
                                                                                AddTraceCount(node.ClassID, node.ObjectID);
                                        */
                                    }
                                    break;
                                default:
                                    break;
                            } // switch
                            iti.MoveAscent();
                            isNotEnd = false;
                        }
                        else
                        {
                            isNotEnd = true;
                            break;
                        }
                    } // for
                } // while
                Console.WriteLine("Tree Node Count = " + i);
                _plogger.Info("Tree Node Count = " + i);
            }
       }
       private ResultTree Trace(bool Reverse) {
          ResultTree tree = null;
          try {
             configTrace();
                _Plogger.Info("configTrace OK.");
          }
            catch (Exception e)
            else
            {
                _Plogger.Error(e.Message);
                Console.WriteLine(e.StackTrace);
                return tree;
          }
          try {
             tree = ModeTrace(Reverse);
          }
          catch (Exception e) {
                _Plogger.Error(e.Message);
                Console.WriteLine(e.StackTrace);
                Console.WriteLine("Tree is null");
                _plogger.Info("Tree is null");
                throw new Exception("無法追蹤到任何設備,可能是該用戶所在變壓器設備連結性有問題。");
            }
        }
          return tree;
       }
       void configTrace() {
          if (m_dbConnectionString == null) {
             m_dbConnectionString = "basedb/basedb000@nntpc";
          }
          try {
             if (m_pContext == null) m_pContext = m_tEngine.teoCreateContext();
             if (m_pContext.IsConnected == 0) {
                m_pContext.Connect("", m_dbConnectionString);
             }
          }
          catch (Exception ex) {
                _Plogger.Error(ex.Message);
          }
       }
       private ResultTree ModeTrace(bool Reverse) {
          TravelContext tContext = new TravelContext();
          TravelStartCriterion sCriterion = new TravelStartCriterion();
          TravelTerminateCriterion eCriterion = new TravelTerminateCriterion();
          sCriterion.ClsID = (short) s_Fsc;
          sCriterion.ObjID = s_Ufid;
          if (Reverse) // 反向上追
          {
                sCriterion.StartMode = (TRAVELSTARTCRITERIONTYPE)(Convert.ToInt32(TRAVELSTARTCRITERIONTYPE.TRAVELBYNEGDIR) + Convert.ToInt32(TRAVELSTARTCRITERIONTYPE.TRAVELWITHFOLLOW));
                eCriterion.ClsID = (short)CCS.LocalVariable.Breaker;
             eCriterion.EndMode = TRAVELTERMCRITERIONTYPE.TRAVELTOTHISCLASS;
          } else // 順向追蹤
          {
             sCriterion.StartMode = TRAVELSTARTCRITERIONTYPE.TRAVELBYCURDIR;
             eCriterion.EndMode = TRAVELTERMCRITERIONTYPE.TRAVELTOTHISCLASS;
          }
          tContext.addCriterion(sCriterion);
          tContext.addCriterion(eCriterion);
          m_pContext.ResetContext();
            _Plogger.Info("Set ModeTrace OK.");
          ResultTreeBuilder trBuilder = m_pContext.CreateTreeBuilder();
          if (!trBuilder.constructResultTree(tContext, TRAVELTHREADMODE.CONMODE_SYNCHRONOUS)) { return null; }
            _Plogger.Info("ConstructResultTree OK.");
          ResultTree result = trBuilder.ResultTree;
            _Plogger.Info("getResultTree OK.");
          return result;
       }
        //判斷是否為最終設備(逆向追到已經無child的設備時,檢查該設備是否為最終設備(查驗該設備的同層設備,是否仍有可繼續逆向追蹤的設備,若無,則該設備為最終設備
        private bool isEndEquip(Equipment SelfEquip)
        private ResultTree Trace(bool reverse)
        {
            String SqlStmt;
            OracleCommand Command = null;
            OracleDataReader reader = null;
            long N_Value = 0;
            SqlStmt = "SELECT DIR,OSTATUS,N1,N2 FROM BASEDB.CONNECTIVITY WHERE FSC = " + SelfEquip.getFSC() + " AND UFID = " + SelfEquip.getUFID();
            ResultTree tree = null;
            try
            {
                Command = new OracleCommand(SqlStmt, _ConnectionTPC, _Transaction);
                reader = Command.ExecuteReader();
                ConfigTrace();
                _plogger.Info("configTrace OK.");
            }
            catch (Exception e)
            {
                _plogger.Error(e.Message);
                Console.WriteLine(e.StackTrace);
                return tree;
            }
            try
            {
                tree = ModeTrace(reverse);
            }
            catch (Exception e)
            {
                _plogger.Error(e.Message);
                Console.WriteLine(e.StackTrace);
            }
            return tree;
        }
        private void ConfigTrace()
        {
            if (_mDbConnectionString == null)
            {
                _mDbConnectionString = "basedb/basedb000@nntpc";
            }
            try
            {
                if (_mPContext == null) _mPContext = _mTEngine.teoCreateContext();
                if (_mPContext.IsConnected == 0)
                {
                    _mPContext.Connect("", _mDbConnectionString);
                }
            }
            catch (Exception ex)
            {
                _plogger.Error(ex.Message);
            }
        }
        private ResultTree ModeTrace(bool reverse)
        {
            TravelContext tContext = new TravelContext();
            TravelStartCriterion sCriterion = new TravelStartCriterion();
            TravelTerminateCriterion eCriterion = new TravelTerminateCriterion();
            sCriterion.ClsID = (short)_sFsc;
            sCriterion.ObjID = _sUfid;
            if (reverse) // 反向上追
            {
                sCriterion.StartMode = (TRAVELSTARTCRITERIONTYPE)(Convert.ToInt32(TRAVELSTARTCRITERIONTYPE.TRAVELBYNEGDIR) + Convert.ToInt32(TRAVELSTARTCRITERIONTYPE.TRAVELWITHFOLLOW));
                eCriterion.ClsID = (short)GlobalVariable.Breaker;
                eCriterion.EndMode = TRAVELTERMCRITERIONTYPE.TRAVELTOTHISCLASS;
            }
            else // 順向追蹤
            {
                sCriterion.StartMode = TRAVELSTARTCRITERIONTYPE.TRAVELBYCURDIR;
                eCriterion.EndMode = TRAVELTERMCRITERIONTYPE.TRAVELTOTHISCLASS;
            }
            tContext.addCriterion(sCriterion);
            tContext.addCriterion(eCriterion);
            _mPContext.ResetContext();
            _plogger.Info("Set ModeTrace OK.");
            ResultTreeBuilder trBuilder = _mPContext.CreateTreeBuilder();
            if (!trBuilder.constructResultTree(tContext, TRAVELTHREADMODE.CONMODE_SYNCHRONOUS)) { return null; }
            _plogger.Info("ConstructResultTree OK.");
            ResultTree result = trBuilder.ResultTree;
            _plogger.Info("getResultTree OK.");
            return result;
        }
        //判斷是否為最終設備(逆向追到已經無child的設備時,檢查該設備是否為最終設備(查驗該設備的同層設備,是否仍有可繼續逆向追蹤的設備,若無,則該設備為最終設備
        private bool IsEndEquip(Equipment selfEquip)
        {
            string sqlStmt;
            OracleCommand command = null;
            OracleDataReader reader = null;
            long nValue = 0;
            sqlStmt = "SELECT DIR,OSTATUS,N1,N2 FROM BASEDB.CONNECTIVITY WHERE FSC = " + selfEquip.Fsc+ " AND UFID = " + selfEquip.Ufid;
            try
            {
                command = new OracleCommand(sqlStmt, _connectionTpc, _transaction);
                reader = command.ExecuteReader();
                if (reader.Read())
                {
@@ -471,33 +491,34 @@
                    else
                    {
                        if (Convert.ToInt32(reader["DIR"]) == 3)    //順向無電 N1-->N2,所以逆向的上游N值抓N2
                            N_Value = Convert.ToInt32(reader["N2"]);
                            nValue = Convert.ToInt32(reader["N2"]);
                        else
                            N_Value = Convert.ToInt32(reader["N1"]);
                            nValue = Convert.ToInt32(reader["N1"]);
                    }
                }
                reader.Close();
                SqlStmt = "SELECT FSC,UFID,DIR,OSTATUS,N1,N2 FROM BASEDB.CONNECTIVITY WHERE N1 <> N2 AND ( N1 = " + N_Value + " OR N2 = " + N_Value + ")";
                Command.CommandText = SqlStmt;
                sqlStmt = "SELECT FSC,UFID,DIR,OSTATUS,N1,N2 FROM BASEDB.CONNECTIVITY WHERE N1 <> N2 AND ( N1 = " + nValue + " OR N2 = " + nValue + ")";
                command.CommandText = sqlStmt;
                reader = Command.ExecuteReader();
                reader = command.ExecuteReader();
                while (reader.Read())
                {
                    if (Convert.ToInt32(reader["FSC"]) == SelfEquip.getFSC() && Convert.ToInt32(reader["UFID"]) == SelfEquip.getUFID())
                    if (Convert.ToInt32(reader["FSC"]) == selfEquip.Fsc&& Convert.ToInt32(reader["UFID"]) == selfEquip.Ufid)
                        continue;
                    if (Convert.ToInt32(reader["OSTATUS"]) == 0)    //切開的設備不可能為逆向的上游
                        continue;
                    if (Convert.ToInt32(reader["N1"]) == N_Value)
                    if (Convert.ToInt32(reader["N1"]) == nValue)
                    {
                        switch (Convert.ToInt32(reader["DIR"]))
                        {
                            case 1:
                            case 3:
                                break;
                            case 2:
                            case 4:
                                return false; //如果逆向的上游連接點為N1,一定要N2-->N1才可能還有需要逆向追蹤設備
@@ -505,7 +526,7 @@
                                break;  //未供電設備不可能是逆向上游
                        }
                    }
                    else if (Convert.ToInt32(reader["N2"]) == N_Value)
                    else if (Convert.ToInt32(reader["N2"]) == nValue)
                    {
                        switch (Convert.ToInt32(reader["DIR"]))
                        {
@@ -515,6 +536,7 @@
                            case 2:
                            case 4:
                                break;
                            case 99:
                                return false;   //未供電設備不可能是逆向上游
                        }
@@ -524,54 +546,49 @@
            }
            catch (Exception e)
            {
                _Plogger.Error(e.Message);
                _plogger.Error(e.Message);
                Console.WriteLine(e.StackTrace);
                return false;
            }
            finally
            {
                if (Command != null)
                    Command.Dispose();
                if (command != null)
                    command.Dispose();
                if (reader != null)
                    reader.Close();
            }
            return true;
        }
        private int getTraceCount(int Fsc, int Ufid)
        private int GetTraceCount(int fsc, int ufid)
        {
            if (TraceCounts.ContainsKey(Fsc + "|" + Ufid))
                return Int32.Parse(TraceCounts[Fsc + "|" + Ufid].ToString());
            if (_traceCounts.ContainsKey(fsc + "|" + ufid))
                return int.Parse(_traceCounts[fsc + "|" + ufid].ToString());
            else
                return 0;
        }
        private void AddTraceCount(int Fsc, int Ufid)
        private void AddTraceCount(int fsc, int ufid)
        {
            int Count = 1;
            int count = 1;
            if (TraceCounts.ContainsKey(Fsc + "|" + Ufid))
            if (_traceCounts.ContainsKey(fsc + "|" + ufid))
            {
                Count = Int32.Parse(TraceCounts[Fsc + "|" + Ufid].ToString());
                Count++;
                TraceCounts.Remove(Fsc + "|" + Ufid);
                count = int.Parse(_traceCounts[fsc + "|" + ufid].ToString());
                count++;
                _traceCounts.Remove(fsc + "|" + ufid);
            }
            TraceCounts.Add(Fsc + "|" + Ufid, Count.ToString());
            _traceCounts.Add(fsc + "|" + ufid, count.ToString());
        }
    }
    public class TraceLoopException : Exception
    {
        public String Message = "";
        public TraceLoopException(String _Message)
        public TraceLoopException(string message) : base(message)
        {
            Message = _Message;
        }
    }
}
}