TDengine在NetCore中数据查询的使用

1、封装为帮助类的方式调用

仅需在配置类中增加TDengine节点的连接信息:http://localhost:6041

cs 复制代码
using System.Configuration;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Utils
{
    public class TDengineDataHelper
    {
        private static readonly Lazy<TDengineDataHelper> _instance = new Lazy<TDengineDataHelper>(() => new TDengineDataHelper());
        private HttpClient _httpClient = null;
        private readonly string _authToken;
        private static readonly string _baseUrl = ConfigurationManager.AppSettings["TDengine"] ?? throw new InvalidOperationException("TDengine is not configured.");
        public TDengineDataHelper()
        {
            _httpClient= new HttpClient();

            // Basic Authentication
            var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes($"root:taosdata"));
            _authToken = $"Basic {authString}";
            _httpClient.Timeout = TimeSpan.FromSeconds(30);
        }

        // 单例实例访问点
        public static TDengineDataHelper Instance => _instance.Value;

        /// <summary>
        /// TDengien数据查询
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public async Task<TDengineResponse<T>> ExecuteQueryAsync<T>(string sql, string? db = null)
        {
            try
            {
                var requestUrl = $"{_baseUrl}/rest/sql";
                if (!string.IsNullOrEmpty(db))
                {
                    requestUrl += $"/{db}";
                }
                // 添加 row_with_meta 参数
                var queryParams = new Dictionary<string, string>();
                queryParams.Add("row_with_meta", "true");
                if (queryParams.Count>0)
                {
                    requestUrl += "?" + string.Join("&", queryParams.Select(kvp => $"{kvp.Key}={kvp.Value}"));
                }
                var request = new HttpRequestMessage(HttpMethod.Post, requestUrl);
                request.Headers.Add("Authorization", _authToken);
                request.Content = new StringContent(sql, Encoding.UTF8, "application/json");

                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode();

                var result = await response.Content.ReadAsStringAsync();
                // 解析原始响应
                var responseResult = JsonSerializer.Deserialize<TDengineResponse<T>>(result);

                if (responseResult?.Code != 0)
                {
                    return null;
                }
                else
                {
                    return responseResult;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                return null;
            }
        }
        
        
        // 释放资源
        public void Dispose()
        {
            _httpClient?.Dispose();
        }
        /// <summary>
        /// 格式化返回结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tdengineJsonResponse"></param>
        /// <returns></returns>
        public static List<T> GetFormateData<T>(string tdengineJsonResponse)
        {
            // 解析原始响应
            var response = JsonSerializer.Deserialize<TDengineResponse<T>>(tdengineJsonResponse);

            if (response?.Code != 0)
            {
                return new List<T>();
            }
            else
            {
                return response.Data;
            }

        }

        // 内部类用于解析TDengine响应
        public class TDengineResponse<T>
        {
            [JsonPropertyName("code")]
            public int Code { get; set; }

            [JsonPropertyName("column_meta")]
            public List<List<object>> ColumnMeta { get; set; }

            [JsonPropertyName("data")]
            public List<T> Data { get; set; }

            [JsonPropertyName("rows")]
            public int Rows { get; set; }
        }

    }
}

2、使用依赖注入的方式调用

(1)创建服务注册扩展类,实现对服务webSocket连接信息的注入

cs 复制代码
public static class TDengineServiceExtensions
{
    public static IServiceCollection AddTDengine(
        this IServiceCollection services,
        IConfiguration configuration,
        Action<TDengineOptions> configureOptions = null)
    {
        // 绑定配置
        var options = new TDengineOptions();
        configuration.GetSection("TDengine").Bind(options);

        // 允许外部配置覆盖
        configureOptions?.Invoke(options);

        // 注册选项
        services.AddSingleton(Options.Create(options));

        // 注册 HttpClient(使用命名客户端)
        services.AddHttpClient("TDengineClient", client =>
        {
            client.BaseAddress = new Uri(options.ConnectionUrl);
            client.Timeout = TimeSpan.FromSeconds(options.TimeoutSeconds);

            var authString = Convert.ToBase64String(
                Encoding.UTF8.GetBytes($"{options.Username}:{options.Password}"));
            client.DefaultRequestHeaders.Authorization =
                new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
            client.DefaultRequestHeaders.Accept.Add(
                new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
        });

        // 注册主服务
        services.AddScoped<ITDengineService, TDengineDataService>();

        return services;
    }

}
public class TDengineOptions
{
    public string ConnectionUrl { get; set; } = "http://localhost:6041";
    public string Username { get; set; } = "root";
    public string Password { get; set; } = "taosdata";
    public int TimeoutSeconds { get; set; } = 10;
}

(2)数据返回实体

cs 复制代码
public class TDengineResponse<T>
{
    [JsonPropertyName("code")]
    public int Code { get; set; }

    [JsonPropertyName("column_meta")]
    public List<List<object>> ColumnMeta { get; set; }

    [JsonPropertyName("data")]
    public List<T> Data { get; set; }

    [JsonPropertyName("rows")]
    public int Rows { get; set; }
}

(3)服务接口类

cs 复制代码
 public interface ITDengineService
 {
     Task<TDengineResponse<T>> ExecuteQueryAsync<T>(string sql, string? db = null);
     void Dispose();
 }

(4)服务实现类

cs 复制代码
 public class TDengineDataService : ITDengineService, IDisposable
 {
     private readonly HttpClient _httpClient;
     private readonly TDengineOptions _options;
     private readonly ILogger<TDengineDataService> _logger;

     public TDengineDataService(IHttpClientFactory httpClientFactory, IOptions<TDengineOptions> options,ILogger<TDengineDataService> logger)
     {
         _logger = logger;
         _options = options.Value;

         // 从工厂获取命名客户端
         _httpClient = httpClientFactory.CreateClient("TDengineClient");
     }

     public void Dispose()
     {
         _httpClient?.Dispose();
     }

     public async Task<TDengineResponse<T>> ExecuteQueryAsync<T>(string sql, string? db = null)
     {
         try
         {
             var endpoint = string.IsNullOrEmpty(db) ? "rest/sql" : $"rest/sql/{db}";
             var requestUrl = $"{endpoint}?row_with_meta=true";

             var request = new HttpRequestMessage(HttpMethod.Post, requestUrl);
             request.Content = new StringContent(sql, Encoding.UTF8, "application/json");

             var response = await _httpClient.SendAsync(request);
             response.EnsureSuccessStatusCode();

             var result = await response.Content.ReadAsStringAsync();
             var responseResult = JsonSerializer.Deserialize<TDengineResponse<T>>(result);

             if (responseResult?.Code != 0)
             {
                 _logger.LogWarning("TDengine query failed with code: {Code}", responseResult?.Code);
                 return null;
             }

             return responseResult;
         }
         catch (Exception ex)
         {
             _logger.LogError(ex, "TDengine query error");
             return null;
         }
     }
 }
相关推荐
数据猿21 小时前
【金猿CIO展】上海纽约大学信息技术部高级主任常潘:大数据铸基,AI赋能,从数字化校园向智慧有机体的十年跃迁
大数据·人工智能
李@十一₂⁰21 小时前
git多分支管理
大数据·git·elasticsearch
yumgpkpm1 天前
AI评判:信创替代对Cloudera CDH CDP Hadoop大数据平台有何影响?
大数据·hive·oracle·flink·kafka·hbase·cloudera
小四的快乐生活1 天前
大数据SQL诊断(采集、分析、优化方案)
大数据·数据库·sql
DeepFlow 零侵扰全栈可观测1 天前
3分钟定位OA系统GC瓶颈:DeepFlow全栈可观测平台实战解析
大数据·运维·人工智能·云原生·性能优化
天远API1 天前
拒绝多头借贷:详解天远多头借贷行业风险版API的Python对接与数据清洗
大数据·api
韦东东1 天前
Text2SQL案例演示:信贷风控策略场景(Coze工作流版)
大数据·人工智能·大模型·text2sql·coze·信贷策略
johnnyAndCode1 天前
ES迁移工具,纯手搓,灵活好用效率高
大数据·elasticsearch·搜索引擎
智能化咨询1 天前
(112页PPT)数字化转型制造业企业数据治理平台规划方案(附下载方式)
大数据·运维·人工智能