一、需求描述 由於WTM預設只支持查詢關係型資料庫,但實際生產過程中,我們的數據可能會存在時序資料庫。 WTM LayUI的架構下,實現通過查詢InfluxDB時序資料庫數據,並將數據放到DataTable中。 二、解決思路 通過Influx語法,將數據查詢出來放到List的容器中,然後再在GetS ...
一、需求描述
由於WTM預設只支持查詢關係型資料庫,但實際生產過程中,我們的數據可能會存在時序資料庫。
WTM LayUI的架構下,實現通過查詢InfluxDB時序資料庫數據,並將數據放到DataTable中。
二、解決思路
通過Influx語法,將數據查詢出來放到List的容器中,然後再在GetSearchQuery方法中返回。 這樣無論查詢數據放到DataTable還是導出都可以使用。
三、代碼實現
GetSearchQuery方法的實現:
public override IOrderedQueryable<HParameterMonitoring_View> GetSearchQuery() { var list= GetInfluxDBData().Result; return list.AsQueryable().OrderBy(x=>x.HParameterMonitoring_MachineCode); }
查詢InfluxDB數據將其放到List容器中:
private async Task<List<HParameterMonitoring_View>> GetInfluxDBData() { StringBuilder query = new StringBuilder(); StringBuilder queryCount = new StringBuilder(); string machineId = Searcher.SelectedMachineId.ToString(); var dicParm = DC.Set<CMachParm>().CheckContain(Searcher.HPTHAlarmParameterIds, x => x.ID).ToDictionary(s => s.NameEN, v => v); // List<string> paraList = dicParm.Keys.ToList(); List<ParamName> paraList = new List<ParamName>(); foreach (var para in dicParm) { ParamName obj = new ParamName() { Name_Cn = para.Value.NameCN, Name_En = para.Value.NameEN, Unit = para.Value.Unit, }; paraList.Add(obj); }; int queryStart = DateHelper.ConvertDateTimeInt(Searcher.DateStart ?? DateTime.Now.AddMinutes(-5)); int queryEnd = DateHelper.ConvertDateTimeInt(Searcher.DateEnd ?? DateTime.Now); List<HParameterMonitoring_View> objList = new List<HParameterMonitoring_View>(); using (var client = InfluxDBClientFactory.Create(Wtm.ConfigInfo.AppSettings["InfluxDBUrl"], Wtm.ConfigInfo.AppSettings["InfluxDBToken"].ToCharArray())) { client.EnableGzip();//此方法將數據壓縮,就不會導致超時的發生 //bool IsGzipEnabled=client.IsGzipEnabled(); query.Append($"from(bucket:\"{Wtm.ConfigInfo.AppSettings["InfluxDBBucket"]}\")"); query.Append($@"|> range(start: {queryStart},stop:{queryEnd})"); query.Append("|> filter(fn: (r) => r[\"_measurement\"] == \"cncinfo\")"); query.Append($"|> filter(fn: (r) => r[\"machineId\"] == \"{machineId}\")"); if (paraList.Count > 0) { query.Append($"|> filter(fn: (r) => 1!=1");//or 就要是false 因為false或什麼 就是什麼 foreach (var para in paraList) { query.Append($" or r[\"_field\"] == \"{para.Name_En}\"");//相當於select那些列 } query.Append(")"); } var fluxTable = await client.GetQueryApi().QueryAsync(query.ToString(), Wtm.ConfigInfo.AppSettings["InfluxDBOrg"],cancellationToken:System.Threading.CancellationToken.None); //int z = (Searcher.Page - 1) * Searcher.Limit; for (int i = 0; i < fluxTable.Count; i++) {//i是參數 for (int j = 0; j < fluxTable[i].Records.Count; j++) {//j是數據 string time = fluxTable[i].Records[j].GetTimeInDateTime()?.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss"); string fieldOri = fluxTable[i].Records[j].GetField(); Dictionary<string, object> values = fluxTable[i].Records[j].Values; string NameCn = ""; string Unit = ""; foreach (var item in paraList) { if (item.Name_En == fieldOri) { NameCn = item.Name_Cn; Unit = item.Unit; } }; HParameterMonitoring_View obj = new HParameterMonitoring_View() { HParameterMonitoring_MachineCode = values["eqname"]?.ToString(), HParameterMonitoring_Param = fieldOri, HParameterMonitoring_ParamCn = NameCn, HParameterMonitoring_Value = values["_value"]?.ToString() + Unit, HParameterMonitoring_UpdateTime = time, }; objList.Add(obj); } } }; return objList; }
四、改善建議
改善點1:每次查詢出來都是不帶分頁的整個list,然後才進行分頁
由於要使用WTM的GetSearchQuery,而WTM的分頁和排序是在執行完GetSearchQuery方法之後,故沒法分頁查詢。如果要分頁查詢,只能自己寫查詢資料庫方法不使用GetSearchQuery方法,而是在查詢時序資料庫的時候,直接用limit進行分頁。