You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ParseTDengineRestResponse.cs 5.8KB

преди 1 година
преди 1 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. using Newtonsoft.Json;
  2. using System.Reflection;
  3. using System.Text.RegularExpressions;
  4. namespace HealthMonitor.Model.Service.Mapper
  5. {
  6. public class ParseTDengineRestResponse<T>
  7. {
  8. #region 泛化解析
  9. private List<T> ParseDataList(dynamic data)
  10. {
  11. List<T> result = new();
  12. foreach (var row in data)
  13. {
  14. var model = CreateInstance<T>();
  15. for (int i = 0; i < ColumnMeta.Count; i++)
  16. {
  17. var columnName = ColumnMeta[i][0].ToString()!;
  18. var columnType = ColumnMeta[i][1].ToString()!;
  19. string pattern = @"\((.*?)\)"; // 匹配括号内的任意字符(非贪婪模式)
  20. // 使用正则表达式进行匹配
  21. Match match = Regex.Match(columnName, pattern);
  22. // 检查是否有匹配项
  23. if (match.Success)
  24. {
  25. // 提取括号内的内容
  26. string contentInsideParentheses = match.Groups[1].Value;
  27. columnName = contentInsideParentheses;
  28. }
  29. var columnValue = ConvertValue(row[i], columnType!);
  30. SetProperty(model, columnName!, columnValue);
  31. }
  32. result.Add(model);
  33. }
  34. return result;
  35. }
  36. private static T CreateInstance<U>()
  37. {
  38. return Activator.CreateInstance<T>();
  39. }
  40. private static void SetProperty<TValue>(T target, string propertyName, TValue value)
  41. {
  42. var property = typeof(T).GetProperties()
  43. .FirstOrDefault(p => GetJsonPropertyName(p) == propertyName);
  44. if (property != null)
  45. {
  46. property.SetValue(target, value);
  47. }
  48. }
  49. private static object ConvertValue(object value, string columnType)
  50. {
  51. return columnType.ToUpper() switch
  52. {
  53. "TIMESTAMP" => DateTime.TryParse(value.ToString(),out DateTime dateTimeValue)? dateTimeValue:DateTime.Now,
  54. "NCHAR" or "VARCHAR" => value==null?string.Empty:value.ToString()!,
  55. "INT" => int.TryParse(value.ToString(), out int intValue)? intValue:0,
  56. "TINYINT" => Convert.ToByte(value),
  57. "BOOL" => Convert.ToBoolean(value),
  58. "FLOAT" => float.TryParse(value.ToString(), out float floatValue)? floatValue : 0f,
  59. _ => value,
  60. } ;
  61. }
  62. private static string GetJsonPropertyName(PropertyInfo property)
  63. {
  64. var attribute = (JsonPropertyAttribute)Attribute.GetCustomAttribute(property, typeof(JsonPropertyAttribute))!;
  65. return attribute?.PropertyName ?? property.Name;
  66. }
  67. private List<T> ParseData = default!;
  68. #endregion
  69. #region 响应解析
  70. [JsonProperty("code")]
  71. public int Code { get; set; }
  72. [JsonProperty("column_meta")]
  73. public List<List<object>> ColumnMeta { get; set; } = new List<List<object>>();
  74. [JsonProperty("rows")]
  75. public int Rows { get; set; }
  76. [JsonProperty("data")]
  77. public dynamic Data
  78. {
  79. get => ParseData;
  80. set => ParseData = ParseDataList(value);
  81. }
  82. #endregion
  83. #region Linq
  84. public IEnumerable<TResult> Select<TResult>(Func<T, TResult> selector)
  85. {
  86. return ParseData.Select(selector);
  87. }
  88. public IEnumerable<T> Select()
  89. {
  90. return ParseData;
  91. }
  92. #endregion
  93. #region 统计算法
  94. /// <summary>
  95. /// 统计算法
  96. /// </summary>
  97. /// <param name="valueSelector"></param>
  98. /// <param name="numToRemove"></param>
  99. /// <returns></returns>
  100. /// <exception cref="ArgumentException"></exception>
  101. public float AverageAfterRemovingOneMinMaxRef(Func<T, float> valueSelector, int numToRemove, out int[] collection, out int max, out int min)
  102. {
  103. var values = ParseData.Select(valueSelector).ToList();
  104. collection = values.Select(i => (int)i).ToArray();
  105. if (values.Count <= 2)
  106. {
  107. throw new ArgumentException("Not enough elements to remove.");
  108. }
  109. // Remove the specified number of minimum and maximum values
  110. //values.RemoveAll(_ => _ == values.Min());
  111. //values.RemoveAll(_ => _ == values.Max());
  112. max = (int)values.Max();
  113. min = (int)values.Min();
  114. values.Remove(max);
  115. values.Remove(min);
  116. // Remove values less than the specified threshold
  117. values.RemoveAll(_ => _ > numToRemove);
  118. // Calculate and return the average of the remaining values
  119. return values.Average();
  120. }
  121. public decimal AverageAfterRemovingOneMinMaxRef(Func<T, decimal> valueSelector, int refValue)
  122. {
  123. var values = ParseData.Select(valueSelector).ToList();
  124. // Remove the specified number of minimum and maximum values
  125. //values.RemoveAll(_ => _ == values.Min());
  126. //values.RemoveAll(_ => _ == values.Max());
  127. values.Remove(values.Max());
  128. values.Remove(values.Min());
  129. // Remove values less than the specified threshold
  130. values.RemoveAll(_ => _ > refValue);
  131. if (values.Count < 2)
  132. {
  133. // throw new ArgumentException("数据不够不能计算");
  134. // 平均值为0,说明数据不足,不能计算增量值
  135. return 0M;
  136. }
  137. // Calculate and return the average of the remaining values
  138. return values.Average();
  139. }
  140. #endregion
  141. }
  142. }