예제 #1
0
        private void reCalculateLink(string calculateName, DateTimeOffset date)
        {
            try
            {
                //生成拓扑图
                ALGraph.MyGraph graph = new ALGraph.MyGraph();

                constructGraph(calculateName, graph, date);

                System.Collections.ArrayList toplist = graph.topSort();
                if (toplist.Count != graph.Vexnum)
                {
                    throw new Exception("仪器公式存在循环依赖");
                }

                //根据拓扑顺序依次更新

                for (int i = 0; i < toplist.Count; i++)
                {
                    string csn = (string)toplist[i];
                    //不必更新本身
                    if (csn != calculateName)
                    {
                        AppIntegratedInfo otherApp = new AppIntegratedInfo(csn, date);
                        reCalcValues(otherApp, null, date);
                        //要更新数据
                        otherApp.Update();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("计算关联测点错误 " + ex.Message);
            }
        }
예제 #2
0
        public AppIntegratedInfo(AppIntegratedInfo clonedAppInfo, int topNum, DateTimeOffset?startDate, DateTimeOffset?endDate)
        {
            _dbContext  = clonedAppInfo.DbContext;
            _currentApp = clonedAppInfo.CurrentApp;
            _calcParams = clonedAppInfo.CalcParams;

            SetInfo(_currentApp.AppName, topNum, startDate, endDate);
        }
예제 #3
0
        /// <summary>
        /// 查询离指定时间最近的数据的记录
        /// </summary>

        /// <param name="preConcertDate">指定的时间,也就是预定时间</param>
        /// <param name="days">"最近"这个词所允许的与预期时间相隔最大的天数</param>
        /// <returns></returns>
        public AppIntegratedInfo getAppInfoNearTime(DateTimeOffset preConcertDate, double days)
        {
            AppIntegratedInfo appInfo = null;

            AppIntegratedInfo infoSuffix = new AppIntegratedInfo(this, 1, preConcertDate, null);

            AppIntegratedInfo infoPrefix = new AppIntegratedInfo(this, 1, null, preConcertDate);

            if (infoSuffix.CalcValues.Count == 0 && infoPrefix.CalcValues.Count == 0)
            {
                return(null);
            }

            long after = long.MaxValue, before = long.MaxValue;



            if (infoSuffix.CalcValues.Count != 0)
            {
                after = (infoSuffix.CalcValues[0].Date).Ticks - preConcertDate.Ticks;
            }

            if (infoPrefix.CalcValues.Count != 0)
            {
                before = preConcertDate.Ticks - (infoPrefix.CalcValues[0].Date).Ticks;
            }

            long cha = 0;

            if (after > before)
            {
                cha     = before;
                appInfo = infoPrefix;
            }
            else
            {
                cha     = after;
                appInfo = infoSuffix;
            }

            if (cha > TimeSpan.TicksPerDay * days)
            {
                appInfo = null;
            }

            return(appInfo);
        }
예제 #4
0
        /// <summary>
        /// 将实际的值填充到参数列表中,如果参数没有相应的值,将被赋初值0
        /// </summary>
        /// <param name="list">参数列表</param>
        /// <param name="appCalcName">测点的计算名称</param>
        /// <param name="date">日期</param>
        /// <param name="appendDot">是否将计算名称和点加在参数的前面</param>
        /// <param name="simpleInfo">测点数据信息</param>
        internal static void fillListByCalcName_Date(hammergo.caculator.MyList list, DateTimeOffset date, bool appendDot, AppIntegratedInfo simpleInfo)
        {
            string appCalcName = simpleInfo.CurrentApp.CalculateName;

            foreach (ConstantParam cp in simpleInfo.ConstantParams)
            {
                string key = cp.ParamSymbol;
                if (appendDot)
                {
                    key = String.Format("{0}.{1}", appCalcName, key);
                }
                list.add(key, cp.Val);
            }

            //赋初值0

            foreach (MessureParam mp in simpleInfo.MesParams)
            {
                string key = mp.ParamSymbol;
                if (appendDot)
                {
                    key = String.Format("{0}.{1}", appCalcName, key);
                }
                list.add(key, 0);
            }

            //赋初值0
            foreach (CalculateParam cp in simpleInfo.CalcParams)
            {
                string key = cp.ParamSymbol;
                if (appendDot)
                {
                    key = String.Format("{0}.{1}", appCalcName, key);
                }
                list.add(key, 0);
            }

            //加快速度
            foreach (MessureValue mv in simpleInfo.MesValues.Where(s => s.Date == date))
            {
                MessureParam mp = simpleInfo.MesParams.Find(delegate(MessureParam item) { return(item.Id == mv.ParamId); });

                string key = mp.ParamSymbol;
                if (appendDot)
                {
                    key = String.Format("{0}.{1}", appCalcName, key);
                }

                list[key] = mv.Val.Value;
            }

            //加快速度
            foreach (CalculateValue cv in simpleInfo.CalcValues.Where(s => s.Date == date))
            {
                CalculateParam cp  = simpleInfo.CalcParams.Find(delegate(CalculateParam item) { return(item.Id == cv.ParamId); });
                string         key = cp.ParamSymbol;
                if (appendDot)
                {
                    key = String.Format("{0}.{1}", appCalcName, key);
                }

                list[key] = cv.Val.Value;
            }
        }
예제 #5
0
        /// <summary>
        /// 由于messure values更改了,需要重新计算calc values的值
        /// </summary>
        /// <param name="appInfo"></param>
        /// <param name="currentRow"></param>
        /// <param name="date"></param>
        internal static void reCalcValues(AppIntegratedInfo appInfo, DataRow currentRow, DateTimeOffset date)
        {
            hammergo.caculator.CalcFunction calc = new hammergo.caculator.CalcFunction();
            hammergo.caculator.MyList       list = new hammergo.caculator.MyList();

            //填充自身,要求在appInfo中的数据是更新后的数据
            fillListByCalcName_Date(list, date, false, appInfo);

            //分析此仪器是否引用了其它仪器的数据
            hammergo.caculator.MyList appCalcNameList = new hammergo.caculator.MyList();//引用的其它仪器名称的集合

            var sortedParams = new SortedDictionary <byte, ParamHelper>();



            //这里必须按照calc order 的顺序
            foreach (CalculateParam cp in appInfo.CalcParams)
            {
                Formula formulaEntity = appInfo.AllFormulae.SingleOrDefault(s => s.ParamId == cp.Id && s.StartDate <= date && date < s.EndDate);

                if (formulaEntity == null)
                {
                    throw new Exception(string.Format("找不到对应时间:{0:u}的工式,请检查测点的参数信息", date));
                }

                sortedParams.Add(formulaEntity.CalculateOrder, new ParamHelper {
                    FormulaEntity = formulaEntity, Param = cp
                });

                string formulaString = formulaEntity.FormulaExpression;//获取表达式

                System.Collections.ArrayList vars = calc.getVaribles(formulaString);
                //为了避免对某个测点的数据重复查询,将一次性填充一支仪器的数据


                for (int j = 0; j < vars.Count; j++)
                {
                    string vs  = (string)vars[j];
                    int    pos = vs.IndexOf('.');
                    if (pos != -1)
                    {
                        //引用了其它测点
                        string otherID = vs.Substring(0, pos);
                        appCalcNameList.add(otherID, 0);
                        //避免由于计算时依赖其它仪器,而其它仪器没有此刻的记录时,导致异常
                        list.add(vs, 0);
                    }
                }
            }

            //填充带点的参数
            for (int i = 0; i < appCalcNameList.Length; i++)
            {
                AppIntegratedInfo simpleAppInfo = new AppIntegratedInfo(appCalcNameList.getKey(i), date);
                fillListByCalcName_Date(list, date, true, simpleAppInfo);
            }

            //可以进行表达式求值了

            //根据计算顺序
            for (int i = 0; i < sortedParams.Count; i++)
            {
                var helperobj = sortedParams.ElementAt(i).Value;
                var cp        = helperobj.Param;
                //顺序是以order 升序排列
                string formula = helperobj.FormulaEntity.FormulaExpression;//获取表达式

                double v = calc.compute(formula, list);

                byte precision = cp.PrecisionNum;

                if (precision >= 0)
                {
                    v = Helper.Round(v, precision);
                }



                CalculateValue calcValue = appInfo.CalcValues.Find(delegate(CalculateValue item)
                {
                    return(item.Date == date && item.ParamId == cp.Id);
                });

                if (calcValue == null)
                {
                    //create new object
                    calcValue         = new CalculateValue();
                    calcValue.Date    = date;
                    calcValue.ParamId = cp.Id;

                    appInfo.CalcValues.Add(calcValue);

                    //添加到dbcontext中
                    appInfo.DbContext.AddToCalculateValues(calcValue);
                }

                calcValue.Val = v;

                appInfo.DbContext.UpdateObject(calcValue);

                //在填充时已添加,这里就不能添加
                list[cp.ParamSymbol] = v;

                if (currentRow != null)
                {
                    currentRow[cp.ParamName] = v;
                }
            }
        }
예제 #6
0
        //重新计算相关值,并反映在gridview中
        public static void redirectToObjects(AppIntegratedInfo appInfo, DataRow row, string feildName)
        {
            DateTimeOffset date = (DateTimeOffset)row[PubConstant.timeColumnName];
            MessureParam   mp   = appInfo.MesParams.FirstOrDefault(s => s.ParamName == feildName);

            if (mp != null)
            {
                MessureValue editedValue = appInfo.MesValues.Find(delegate(MessureValue item)
                {
                    return(item.Date == date && item.ParamId == mp.Id);
                });

                if (editedValue == null)
                {
                    //create new object
                    editedValue         = new MessureValue();
                    editedValue.Date    = date;
                    editedValue.ParamId = mp.Id;
                    appInfo.MesValues.Add(editedValue);

                    appInfo.DbContext.AddToMessureValues(editedValue);
                }


                editedValue.Val = (double)row[feildName];

                appInfo.DbContext.UpdateObject(editedValue);

                //recalculate the calc values
                reCalcValues(appInfo, row, date);
            }
            else
            {
                //直接编辑成果值,所有不用计算本测点的数据,但需要更新引用测点的数据
                CalculateParam cp = appInfo.CalcParams.Find(delegate(CalculateParam item)
                {
                    return(item.ParamName == feildName);
                });

                if (cp != null)
                {
                    CalculateValue calcValue = appInfo.CalcValues.Find(delegate(CalculateValue item)
                    {
                        return(item.Date == date && item.ParamId == cp.Id);
                    });

                    if (calcValue == null)
                    {
                        //create new object
                        calcValue         = new CalculateValue();
                        calcValue.Date    = date;
                        calcValue.ParamId = cp.Id;
                        appInfo.CalcValues.Add(calcValue);

                        appInfo.DbContext.AddToCalculateValues(calcValue);
                    }

                    calcValue.Val = (double)row[feildName];

                    //dbcontext标记要更新
                    appInfo.DbContext.UpdateObject(calcValue);
                }
            }

            //may be need reset the filter to null
        }