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;
         }
     }
 }
相关推荐
藦卡机器人4 小时前
中国工业机器人发展现状
大数据·人工智能·机器人
Simon_lca5 小时前
突破合规瓶颈:ZDHC Supplier to Zero(工厂零排放 - 进阶型)体系全攻略
大数据·网络·人工智能·分类·数据挖掘·数据分析·零售
黄焖鸡能干四碗7 小时前
网络安全建设实施方案(Word文件参考下载)
大数据·网络·人工智能·安全·web安全·制造
云境筑桃源哇8 小时前
马踏春风 为爱启航 | 瑞派宠物医院(南部新城旗舰店)盛大开业!打造宠物医疗新标杆!
大数据·宠物
xixixi777779 小时前
2026 年 03 月 20 日 AI+通信+安全行业日报(来更新啦)
大数据·人工智能·安全·ai·大模型·通信
F36_9_9 小时前
大数据治理平台选型避坑:2026 年 8 大主流系统实测
大数据·数据治理
成长之路5149 小时前
【实证分析】A股上市公司企业劳动力需求数据集(2000-2023年)
大数据
奔跑的呱呱牛9 小时前
GeoJSON 在大数据场景下为什么不够用?替代方案分析
java·大数据·servlet·gis·geojson
Lab_AI9 小时前
电池材料行业数据管理新突破:AI4S驱动的科学数据平台正在重塑电池材料开发范式
大数据·人工智能·ai4s·电池材料开发·电池材料研发·电池材料创新·ai材料研发
FindAI发现力量9 小时前
智能工牌:线下销售场景的数字化赋能解决方案
大数据·人工智能·销售管理·ai销售·ai销冠·销售智能体