C# Connector

TDengine.Connector 是 TDengine 提供的 C# 语言连接器。C# 开发人员可以通过它开发存取 TDengine 集群数据的 C# 应用软件。

TDengine.Connector 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、数据订阅、schemaless 数据写入、参数绑定接口数据写入等功能。 TDengine.Connector 自 v3.0.1 起还支持 WebSocket,通过 DSN 建立 WebSocket 连接,提供数据写入、查询、参数绑定接口数据写入等功能。

本文介绍如何在 Linux 或 Windows 环境中安装 TDengine.Connector,并通过 TDengine.Connector 连接 TDengine 集群,进行数据写入、查询等基本操作。

注意:TDengine.Connector 3.x 不兼容 TDengine 2.x,如果在运行 TDengine 2.x 版本的环境下需要使用 C# 连接器请使用 TDengine.Connector 的 1.x 版本 。

TDengine.Connector 的源码托管在 GitHub

支持的平台

支持的平台和 TDengine 客户端驱动支持的平台一致。

版本支持

请参考版本支持列表

支持的功能特性

  • 原生连接
  • WebSocket 连接
  1. 连接管理
  2. 普通查询
  3. 连续查询
  4. 参数绑定
  5. 数据订阅(TMQ)
  6. Schemaless

  7. 连接管理

  8. 普通查询
  9. 连续查询
  10. 参数绑定

安装步骤

安装前准备

安装 TDengine.Connector

  • 使用本地连接
  • 使用 WebSocket 连接

可以在当前 .NET 项目的路径下,通过 dotnet CLI 添加 Nuget package TDengine.Connector 到当前项目。

  1. dotnet add package TDengine.Connector

也可以修改当前项目的 .csproj 文件,添加如下 ItemGroup。

  1. <ItemGroup>
  2. <PackageReference Include="TDengine.Connector" Version="3.0.*" />
  3. </ItemGroup>

需要修改目标项目的 .csproj 项目文件,将 .nupkg 中的 runtimes 目录中的动态库复制到当前项目的 $(OutDir) 目录下。

  1. <ItemGroup>
  2. <PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
  3. </ItemGroup>
  4. <Target Name="copyDLLDependency" BeforeTargets="BeforeBuild">
  5. <ItemGroup>
  6. <DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
  7. </ItemGroup>
  8. <Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
  9. </Target>

注意:TDengine.Connector 自 version>= 3.0.2 的 nuget package 中才会有动态库( taosws.dll,libtaows.so )。

建立连接

  • 原生连接
  • WebSocket 连接

使用 host、username、password、port 等信息建立连接。

  1. using TDengineDriver;
  2. namespace TDengineExample
  3. {
  4. internal class EstablishConnection
  5. {
  6. static void Main(String[] args)
  7. {
  8. string host = "localhost";
  9. short port = 6030;
  10. string username = "root";
  11. string password = "taosdata";
  12. string dbname = "";
  13. var conn = TDengine.Connect(host, username, password, dbname, port);
  14. if (conn == IntPtr.Zero)
  15. {
  16. Console.WriteLine("Connect to TDengine failed");
  17. }
  18. else
  19. {
  20. Console.WriteLine("Connect to TDengine success");
  21. }
  22. TDengine.Close(conn);
  23. TDengine.Cleanup();
  24. }
  25. }
  26. }

使用 DSN 建立 WebSocket 连接 DSN 连接。 描述字符串基本结构如下:

  1. [<protocol>]://[[<username>:<password>@]<host>:<port>][/<database>][?<p1>=<v1>[&<p2>=<v2>]]
  2. |------------|---|-----------|-----------|------|------|------------|-----------------------|
  3. | protocol | | username | password | host | port | database | params |

各部分意义见下表:

  • protocol: 显示指定以何种方式建立连接,例如:ws://localhost:6041 指定以 Websocket 方式建立连接(支持 http/ws )。

  • username/password: 用于创建连接的用户名及密码(默认 root/taosdata )。

  • host/port: 指定创建连接的服务器及端口,WebSocket 连接默认为 localhost:6041

  • database: 指定默认连接的数据库名,可选参数。

  • params:其他可选参数。

  1. using System;
  2. using TDengineWS.Impl;
  3. namespace Examples
  4. {
  5. public class WSConnExample
  6. {
  7. static int Main(string[] args)
  8. {
  9. string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
  10. IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
  11. if (wsConn == IntPtr.Zero)
  12. {
  13. Console.WriteLine("get WS connection failed");
  14. return -1;
  15. }
  16. else
  17. {
  18. Console.WriteLine("Establish connect success.");
  19. // close connection.
  20. LibTaosWS.WSClose(wsConn);
  21. }
  22. return 0;
  23. }
  24. }
  25. }

查看源码

使用示例

写入数据

SQL 写入

  • 原生连接
  • WebSocket 连接
  1. using TDengineDriver;
  2. namespace TDengineExample
  3. {
  4. internal class SQLInsertExample
  5. {
  6. static void Main()
  7. {
  8. IntPtr conn = GetConnection();
  9. try
  10. {
  11. IntPtr res = TDengine.Query(conn, "CREATE DATABASE power");
  12. CheckRes(conn, res, "failed to create database");
  13. res = TDengine.Query(conn, "USE power");
  14. CheckRes(conn, res, "failed to change database");
  15. res = TDengine.Query(conn, "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)");
  16. CheckRes(conn, res, "failed to create stable");
  17. var sql = "INSERT INTO d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000) " +
  18. "d1002 USING power.meters TAGS('California.SanFrancisco', 3) VALUES('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000) " +
  19. "d1003 USING power.meters TAGS('California.LosAngeles', 2) VALUES('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000)('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000) " +
  20. "d1004 USING power.meters TAGS('California.LosAngeles', 3) VALUES('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000)('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)";
  21. res = TDengine.Query(conn, sql);
  22. CheckRes(conn, res, "failed to insert data");
  23. int affectedRows = TDengine.AffectRows(res);
  24. Console.WriteLine("affectedRows " + affectedRows);
  25. TDengine.FreeResult(res);
  26. }
  27. finally
  28. {
  29. TDengine.Close(conn);
  30. }
  31. }
  32. static IntPtr GetConnection()
  33. {
  34. string host = "localhost";
  35. short port = 6030;
  36. string username = "root";
  37. string password = "taosdata";
  38. string dbname = "";
  39. var conn = TDengine.Connect(host, username, password, dbname, port);
  40. if (conn == IntPtr.Zero)
  41. {
  42. throw new Exception("Connect to TDengine failed");
  43. }
  44. else
  45. {
  46. Console.WriteLine("Connect to TDengine success");
  47. }
  48. return conn;
  49. }
  50. static void CheckRes(IntPtr conn, IntPtr res, String errorMsg)
  51. {
  52. if (TDengine.ErrorNo(res) != 0)
  53. {
  54. throw new Exception($"{errorMsg} since: {TDengine.Error(res)}");
  55. }
  56. }
  57. }
  58. }
  59. // output:
  60. // Connect to TDengine success
  61. // affectedRows 8

查看源码

  1. using System;
  2. using TDengineWS.Impl;
  3. namespace Examples
  4. {
  5. public class WSInsertExample
  6. {
  7. static int Main(string[] args)
  8. {
  9. string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
  10. IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
  11. // Assert if connection is validate
  12. if (wsConn == IntPtr.Zero)
  13. {
  14. Console.WriteLine("get WS connection failed");
  15. return -1;
  16. }
  17. else
  18. {
  19. Console.WriteLine("Establish connect success.");
  20. }
  21. string createTable = "CREATE STABLE test.meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);";
  22. string insert = "INSERT INTO test.d1001 USING test.meters TAGS('California.SanFrancisco', 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)" +
  23. "test.d1002 USING test.meters TAGS('California.SanFrancisco', 3) VALUES('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)" +
  24. "test.d1003 USING test.meters TAGS('California.LosAngeles', 2) VALUES('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000)('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000) " +
  25. "test.d1004 USING test.meters TAGS('California.LosAngeles', 3) VALUES('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000)('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)";
  26. IntPtr wsRes = LibTaosWS.WSQuery(wsConn, createTable);
  27. ValidInsert("create table", wsRes);
  28. LibTaosWS.WSFreeResult(wsRes);
  29. wsRes = LibTaosWS.WSQuery(wsConn, insert);
  30. ValidInsert("insert data", wsRes);
  31. LibTaosWS.WSFreeResult(wsRes);
  32. // close connection.
  33. LibTaosWS.WSClose(wsConn);
  34. return 0;
  35. }
  36. static void ValidInsert(string desc, IntPtr wsRes)
  37. {
  38. int code = LibTaosWS.WSErrorNo(wsRes);
  39. if (code != 0)
  40. {
  41. Console.WriteLine($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}");
  42. }
  43. else
  44. {
  45. Console.WriteLine("{0} success affect {2} rows, cost {1} nanoseconds", desc, LibTaosWS.WSTakeTiming(wsRes), LibTaosWS.WSAffectRows(wsRes));
  46. }
  47. }
  48. }
  49. }
  50. // Establish connect success.
  51. // create table success affect 0 rows, cost 3717542 nanoseconds
  52. // insert data success affect 8 rows, cost 2613637 nanoseconds

查看源码

InfluxDB 行协议写入

  1. using TDengineDriver;
  2. namespace TDengineExample
  3. {
  4. internal class InfluxDBLineExample
  5. {
  6. static void Main()
  7. {
  8. IntPtr conn = GetConnection();
  9. PrepareDatabase(conn);
  10. string[] lines = {
  11. "meters,location=California.LosAngeles,groupid=2 current=11.8,voltage=221,phase=0.28 1648432611249",
  12. "meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0.29 1648432611250",
  13. "meters,location=California.LosAngeles,groupid=3 current=10.8,voltage=223,phase=0.29 1648432611249",
  14. "meters,location=California.LosAngeles,groupid=3 current=11.3,voltage=221,phase=0.35 1648432611250"
  15. };
  16. IntPtr res = TDengine.SchemalessInsert(conn, lines, lines.Length, (int)TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS);
  17. if (TDengine.ErrorNo(res) != 0)
  18. {
  19. throw new Exception("SchemalessInsert failed since " + TDengine.Error(res));
  20. }
  21. else
  22. {
  23. int affectedRows = TDengine.AffectRows(res);
  24. Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows");
  25. }
  26. TDengine.FreeResult(res);
  27. }
  28. static IntPtr GetConnection()
  29. {
  30. string host = "localhost";
  31. short port = 6030;
  32. string username = "root";
  33. string password = "taosdata";
  34. string dbname = "";
  35. var conn = TDengine.Connect(host, username, password, dbname, port);
  36. if (conn == IntPtr.Zero)
  37. {
  38. throw new Exception("Connect to TDengine failed");
  39. }
  40. else
  41. {
  42. Console.WriteLine("Connect to TDengine success");
  43. }
  44. return conn;
  45. }
  46. static void PrepareDatabase(IntPtr conn)
  47. {
  48. IntPtr res = TDengine.Query(conn, "CREATE DATABASE test");
  49. if (TDengine.ErrorNo(res) != 0)
  50. {
  51. throw new Exception("failed to create database, reason: " + TDengine.Error(res));
  52. }
  53. res = TDengine.Query(conn, "USE test");
  54. if (TDengine.ErrorNo(res) != 0)
  55. {
  56. throw new Exception("failed to change database, reason: " + TDengine.Error(res));
  57. }
  58. }
  59. }
  60. }

查看源码

OpenTSDB Telnet 行协议写入

  1. using TDengineDriver;
  2. namespace TDengineExample
  3. {
  4. internal class OptsTelnetExample
  5. {
  6. static void Main()
  7. {
  8. IntPtr conn = GetConnection();
  9. try
  10. {
  11. PrepareDatabase(conn);
  12. string[] lines = {
  13. "meters.current 1648432611249 10.3 location=California.SanFrancisco groupid=2",
  14. "meters.current 1648432611250 12.6 location=California.SanFrancisco groupid=2",
  15. "meters.current 1648432611249 10.8 location=California.LosAngeles groupid=3",
  16. "meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3",
  17. "meters.voltage 1648432611249 219 location=California.SanFrancisco groupid=2",
  18. "meters.voltage 1648432611250 218 location=California.SanFrancisco groupid=2",
  19. "meters.voltage 1648432611249 221 location=California.LosAngeles groupid=3",
  20. "meters.voltage 1648432611250 217 location=California.LosAngeles groupid=3",
  21. };
  22. IntPtr res = TDengine.SchemalessInsert(conn, lines, lines.Length, (int)TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED);
  23. if (TDengine.ErrorNo(res) != 0)
  24. {
  25. throw new Exception("SchemalessInsert failed since " + TDengine.Error(res));
  26. }
  27. else
  28. {
  29. int affectedRows = TDengine.AffectRows(res);
  30. Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows");
  31. }
  32. TDengine.FreeResult(res);
  33. }
  34. catch
  35. {
  36. TDengine.Close(conn);
  37. }
  38. }
  39. static IntPtr GetConnection()
  40. {
  41. string host = "localhost";
  42. short port = 6030;
  43. string username = "root";
  44. string password = "taosdata";
  45. string dbname = "";
  46. var conn = TDengine.Connect(host, username, password, dbname, port);
  47. if (conn == IntPtr.Zero)
  48. {
  49. throw new Exception("Connect to TDengine failed");
  50. }
  51. else
  52. {
  53. Console.WriteLine("Connect to TDengine success");
  54. }
  55. return conn;
  56. }
  57. static void PrepareDatabase(IntPtr conn)
  58. {
  59. IntPtr res = TDengine.Query(conn, "CREATE DATABASE test");
  60. if (TDengine.ErrorNo(res) != 0)
  61. {
  62. throw new Exception("failed to create database, reason: " + TDengine.Error(res));
  63. }
  64. res = TDengine.Query(conn, "USE test");
  65. if (TDengine.ErrorNo(res) != 0)
  66. {
  67. throw new Exception("failed to change database, reason: " + TDengine.Error(res));
  68. }
  69. }
  70. }
  71. }

查看源码

OpenTSDB JSON 行协议写入

  1. using TDengineDriver;
  2. namespace TDengineExample
  3. {
  4. internal class OptsJsonExample
  5. {
  6. static void Main()
  7. {
  8. IntPtr conn = GetConnection();
  9. try
  10. {
  11. PrepareDatabase(conn);
  12. string[] lines = { "[{\"metric\": \"meters.current\", \"timestamp\": 1648432611249, \"value\": 10.3, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," +
  13. " {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611249, \"value\": 219, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}, " +
  14. "{\"metric\": \"meters.current\", \"timestamp\": 1648432611250, \"value\": 12.6, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," +
  15. " {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611250, \"value\": 221, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}]"
  16. };
  17. IntPtr res = TDengine.SchemalessInsert(conn, lines, 1, (int)TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED);
  18. if (TDengine.ErrorNo(res) != 0)
  19. {
  20. throw new Exception("SchemalessInsert failed since " + TDengine.Error(res));
  21. }
  22. else
  23. {
  24. int affectedRows = TDengine.AffectRows(res);
  25. Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows");
  26. }
  27. TDengine.FreeResult(res);
  28. }
  29. finally
  30. {
  31. TDengine.Close(conn);
  32. }
  33. }
  34. static IntPtr GetConnection()
  35. {
  36. string host = "localhost";
  37. short port = 6030;
  38. string username = "root";
  39. string password = "taosdata";
  40. string dbname = "";
  41. var conn = TDengine.Connect(host, username, password, dbname, port);
  42. if (conn == IntPtr.Zero)
  43. {
  44. throw new Exception("Connect to TDengine failed");
  45. }
  46. else
  47. {
  48. Console.WriteLine("Connect to TDengine success");
  49. }
  50. return conn;
  51. }
  52. static void PrepareDatabase(IntPtr conn)
  53. {
  54. IntPtr res = TDengine.Query(conn, "CREATE DATABASE test");
  55. if (TDengine.ErrorNo(res) != 0)
  56. {
  57. throw new Exception("failed to create database, reason: " + TDengine.Error(res));
  58. }
  59. res = TDengine.Query(conn, "USE test");
  60. if (TDengine.ErrorNo(res) != 0)
  61. {
  62. throw new Exception("failed to change database, reason: " + TDengine.Error(res));
  63. }
  64. }
  65. }
  66. }

查看源码

参数绑定

  • 原生连接
  • WebSocket 连接
  1. using TDengineDriver;
  2. namespace TDengineExample
  3. {
  4. internal class StmtInsertExample
  5. {
  6. private static IntPtr conn;
  7. private static IntPtr stmt;
  8. static void Main()
  9. {
  10. conn = GetConnection();
  11. try
  12. {
  13. PrepareSTable();
  14. // 1. init and prepare
  15. stmt = TDengine.StmtInit(conn);
  16. if (stmt == IntPtr.Zero)
  17. {
  18. throw new Exception("failed to init stmt.");
  19. }
  20. int res = TDengine.StmtPrepare(stmt, "INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)");
  21. CheckStmtRes(res, "failed to prepare stmt");
  22. // 2. bind table name and tags
  23. TAOS_MULTI_BIND[] tags = new TAOS_MULTI_BIND[2] { TaosMultiBind.MultiBindBinary(new string[] { "California.SanFrancisco" }), TaosMultiBind.MultiBindInt(new int?[] { 2 }) };
  24. res = TDengine.StmtSetTbnameTags(stmt, "d1001", tags);
  25. CheckStmtRes(res, "failed to bind table name and tags");
  26. // 3. bind values
  27. TAOS_MULTI_BIND[] values = new TAOS_MULTI_BIND[4] {
  28. TaosMultiBind.MultiBindTimestamp(new long[2] { 1648432611249, 1648432611749}),
  29. TaosMultiBind.MultiBindFloat(new float?[2] { 10.3f, 12.6f}),
  30. TaosMultiBind.MultiBindInt(new int?[2] { 219, 218}),
  31. TaosMultiBind.MultiBindFloat(new float?[2]{ 0.31f, 0.33f})
  32. };
  33. res = TDengine.StmtBindParamBatch(stmt, values);
  34. CheckStmtRes(res, "failed to bind params");
  35. // 4. add batch
  36. res = TDengine.StmtAddBatch(stmt);
  37. CheckStmtRes(res, "failed to add batch");
  38. // 5. execute
  39. res = TDengine.StmtExecute(stmt);
  40. CheckStmtRes(res, "failed to execute");
  41. // 6. free
  42. TaosMultiBind.FreeTaosBind(tags);
  43. TaosMultiBind.FreeTaosBind(values);
  44. }
  45. finally
  46. {
  47. TDengine.Close(conn);
  48. }
  49. }
  50. static IntPtr GetConnection()
  51. {
  52. string host = "localhost";
  53. short port = 6030;
  54. string username = "root";
  55. string password = "taosdata";
  56. string dbname = "";
  57. var conn = TDengine.Connect(host, username, password, dbname, port);
  58. if (conn == IntPtr.Zero)
  59. {
  60. throw new Exception("Connect to TDengine failed");
  61. }
  62. else
  63. {
  64. Console.WriteLine("Connect to TDengine success");
  65. }
  66. return conn;
  67. }
  68. static void PrepareSTable()
  69. {
  70. IntPtr res = TDengine.Query(conn, "CREATE DATABASE power");
  71. CheckResPtr(res, "failed to create database");
  72. res = TDengine.Query(conn, "USE power");
  73. CheckResPtr(res, "failed to change database");
  74. res = TDengine.Query(conn, "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)");
  75. CheckResPtr(res, "failed to create stable");
  76. }
  77. static void CheckStmtRes(int res, string errorMsg)
  78. {
  79. if (res != 0)
  80. {
  81. Console.WriteLine(errorMsg + ", " + TDengine.StmtErrorStr(stmt));
  82. int code = TDengine.StmtClose(stmt);
  83. if (code != 0)
  84. {
  85. throw new Exception($"failed to close stmt, {code} reason: {TDengine.StmtErrorStr(stmt)} ");
  86. }
  87. }
  88. }
  89. static void CheckResPtr(IntPtr res, string errorMsg)
  90. {
  91. if (TDengine.ErrorNo(res) != 0)
  92. {
  93. throw new Exception(errorMsg + " since:" + TDengine.Error(res));
  94. }
  95. }
  96. }
  97. }

查看源码

  1. using System;
  2. using TDengineWS.Impl;
  3. using TDengineDriver;
  4. using System.Runtime.InteropServices;
  5. namespace Examples
  6. {
  7. public class WSStmtExample
  8. {
  9. static int Main(string[] args)
  10. {
  11. const string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
  12. const string table = "meters";
  13. const string database = "test";
  14. const string childTable = "d1005";
  15. string insert = $"insert into ? using {database}.{table} tags(?,?) values(?,?,?,?)";
  16. const int numOfTags = 2;
  17. const int numOfColumns = 4;
  18. // Establish connection
  19. IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
  20. if (wsConn == IntPtr.Zero)
  21. {
  22. Console.WriteLine($"get WS connection failed");
  23. return -1;
  24. }
  25. else
  26. {
  27. Console.WriteLine("Establish connect success...");
  28. }
  29. // init stmt
  30. IntPtr wsStmt = LibTaosWS.WSStmtInit(wsConn);
  31. if (wsStmt != IntPtr.Zero)
  32. {
  33. int code = LibTaosWS.WSStmtPrepare(wsStmt, insert);
  34. ValidStmtStep(code, wsStmt, "WSStmtPrepare");
  35. TAOS_MULTI_BIND[] wsTags = new TAOS_MULTI_BIND[] { WSMultiBind.WSBindNchar(new string[] { "California.SanDiego" }), WSMultiBind.WSBindInt(new int?[] { 4 }) };
  36. code = LibTaosWS.WSStmtSetTbnameTags(wsStmt, $"{database}.{childTable}", wsTags, numOfTags);
  37. ValidStmtStep(code, wsStmt, "WSStmtSetTbnameTags");
  38. TAOS_MULTI_BIND[] data = new TAOS_MULTI_BIND[4];
  39. data[0] = WSMultiBind.WSBindTimestamp(new long[] { 1538548687000, 1538548688000, 1538548689000, 1538548690000, 1538548691000 });
  40. data[1] = WSMultiBind.WSBindFloat(new float?[] { 10.30F, 10.40F, 10.50F, 10.60F, 10.70F });
  41. data[2] = WSMultiBind.WSBindInt(new int?[] { 223, 221, 222, 220, 219 });
  42. data[3] = WSMultiBind.WSBindFloat(new float?[] { 0.31F, 0.32F, 0.33F, 0.35F, 0.28F });
  43. code = LibTaosWS.WSStmtBindParamBatch(wsStmt, data, numOfColumns);
  44. ValidStmtStep(code, wsStmt, "WSStmtBindParamBatch");
  45. code = LibTaosWS.WSStmtAddBatch(wsStmt);
  46. ValidStmtStep(code, wsStmt, "WSStmtAddBatch");
  47. IntPtr stmtAffectRowPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)));
  48. code = LibTaosWS.WSStmtExecute(wsStmt, stmtAffectRowPtr);
  49. ValidStmtStep(code, wsStmt, "WSStmtExecute");
  50. Console.WriteLine("WS STMT insert {0} rows...", Marshal.ReadInt32(stmtAffectRowPtr));
  51. Marshal.FreeHGlobal(stmtAffectRowPtr);
  52. LibTaosWS.WSStmtClose(wsStmt);
  53. // Free unmanaged memory
  54. WSMultiBind.WSFreeTaosBind(wsTags);
  55. WSMultiBind.WSFreeTaosBind(data);
  56. //check result with SQL "SELECT * FROM test.d1005;"
  57. }
  58. else
  59. {
  60. Console.WriteLine("Init STMT failed...");
  61. }
  62. // close connection.
  63. LibTaosWS.WSClose(wsConn);
  64. return 0;
  65. }
  66. static void ValidStmtStep(int code, IntPtr wsStmt, string desc)
  67. {
  68. if (code != 0)
  69. {
  70. Console.WriteLine($"{desc} failed,reason: {LibTaosWS.WSErrorStr(wsStmt)}, code: {code}");
  71. }
  72. else
  73. {
  74. Console.WriteLine("{0} success...", desc);
  75. }
  76. }
  77. }
  78. }
  79. // WSStmtPrepare success...
  80. // WSStmtSetTbnameTags success...
  81. // WSStmtBindParamBatch success...
  82. // WSStmtAddBatch success...
  83. // WSStmtExecute success...
  84. // WS STMT insert 5 rows...

查看源码

查询数据

同步查询

  • 原生连接
  • WebSocket 连接
  1. using TDengineDriver;
  2. using TDengineDriver.Impl;
  3. using System.Runtime.InteropServices;
  4. namespace TDengineExample
  5. {
  6. internal class QueryExample
  7. {
  8. static void Main()
  9. {
  10. IntPtr conn = GetConnection();
  11. try
  12. {
  13. // run query
  14. IntPtr res = TDengine.Query(conn, "SELECT * FROM meters LIMIT 2");
  15. if (TDengine.ErrorNo(res) != 0)
  16. {
  17. throw new Exception("Failed to query since: " + TDengine.Error(res));
  18. }
  19. // get filed count
  20. int fieldCount = TDengine.FieldCount(res);
  21. Console.WriteLine("fieldCount=" + fieldCount);
  22. // print column names
  23. List<TDengineMeta> metas = LibTaos.GetMeta(res);
  24. for (int i = 0; i < metas.Count; i++)
  25. {
  26. Console.Write(metas[i].name + "\t");
  27. }
  28. Console.WriteLine();
  29. // print values
  30. List<Object> resData = LibTaos.GetData(res);
  31. for (int i = 0; i < resData.Count; i++)
  32. {
  33. Console.Write($"|{resData[i].ToString()} \t");
  34. if (((i + 1) % metas.Count == 0))
  35. {
  36. Console.WriteLine("");
  37. }
  38. }
  39. Console.WriteLine();
  40. // Free result after use
  41. TDengine.FreeResult(res);
  42. }
  43. finally
  44. {
  45. TDengine.Close(conn);
  46. }
  47. }
  48. static IntPtr GetConnection()
  49. {
  50. string host = "localhost";
  51. short port = 6030;
  52. string username = "root";
  53. string password = "taosdata";
  54. string dbname = "power";
  55. var conn = TDengine.Connect(host, username, password, dbname, port);
  56. if (conn == IntPtr.Zero)
  57. {
  58. throw new Exception("Connect to TDengine failed");
  59. }
  60. else
  61. {
  62. Console.WriteLine("Connect to TDengine success");
  63. }
  64. return conn;
  65. }
  66. }
  67. }
  68. // output:
  69. // Connect to TDengine success
  70. // fieldCount=6
  71. // ts current voltage phase location groupid
  72. // 1648432611249 10.3 219 0.31 California.SanFrancisco 2
  73. // 1648432611749 12.6 218 0.33 California.SanFrancisco 2

查看源码

  1. using System;
  2. using TDengineWS.Impl;
  3. using System.Collections.Generic;
  4. using TDengineDriver;
  5. namespace Examples
  6. {
  7. public class WSQueryExample
  8. {
  9. static int Main(string[] args)
  10. {
  11. string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
  12. IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
  13. if (wsConn == IntPtr.Zero)
  14. {
  15. Console.WriteLine("get WS connection failed");
  16. return -1;
  17. }
  18. else
  19. {
  20. Console.WriteLine("Establish connect success.");
  21. }
  22. string select = "select * from test.meters";
  23. // optional:wsRes = LibTaosWS.WSQuery(wsConn, select);
  24. IntPtr wsRes = LibTaosWS.WSQueryTimeout(wsConn, select, 1);
  25. // Assert if query execute success.
  26. int code = LibTaosWS.WSErrorNo(wsRes);
  27. if (code != 0)
  28. {
  29. Console.WriteLine($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}");
  30. LibTaosWS.WSFreeResult(wsRes);
  31. return -1;
  32. }
  33. // get meta data
  34. List<TDengineMeta> metas = LibTaosWS.WSGetFields(wsRes);
  35. // get retrieved data
  36. List<object> dataSet = LibTaosWS.WSGetData(wsRes);
  37. // do something with result.
  38. foreach (var meta in metas)
  39. {
  40. Console.Write("{0} {1}({2}) \t|\t", meta.name, meta.TypeName(), meta.size);
  41. }
  42. Console.WriteLine("");
  43. for (int i = 0; i < dataSet.Count;)
  44. {
  45. for (int j = 0; j < metas.Count; j++)
  46. {
  47. Console.Write("{0}\t|\t", dataSet[i]);
  48. i++;
  49. }
  50. Console.WriteLine("");
  51. }
  52. // Free result after use.
  53. LibTaosWS.WSFreeResult(wsRes);
  54. // close connection.
  55. LibTaosWS.WSClose(wsConn);
  56. return 0;
  57. }
  58. }
  59. }
  60. // Establish connect success.
  61. // ts TIMESTAMP(8) | current FLOAT(4) | voltage INT(4) | phase FLOAT(4) | location BINARY(64) | groupid INT(4) |
  62. // 1538548685000 | 10.8 | 223 | 0.29 | California.LosAngeles | 3 |
  63. // 1538548686500 | 11.5 | 221 | 0.35 | California.LosAngeles | 3 |
  64. // 1538548685500 | 11.8 | 221 | 0.28 | California.LosAngeles | 2 |
  65. // 1538548696600 | 13.4 | 223 | 0.29 | California.LosAngeles | 2 |
  66. // 1538548685000 | 10.3 | 219 | 0.31 | California.SanFrancisco | 2 |
  67. // 1538548695000 | 12.6 | 218 | 0.33 | California.SanFrancisco | 2 |
  68. // 1538548696800 | 12.3 | 221 | 0.31 | California.SanFrancisco | 2 |
  69. // 1538548696650 | 10.3 | 218 | 0.25 | California.SanFrancisco | 3 |

查看源码

异步查询

  1. using System;
  2. using System.Collections.Generic;
  3. using TDengineDriver;
  4. using TDengineDriver.Impl;
  5. using System.Runtime.InteropServices;
  6. namespace TDengineExample
  7. {
  8. public class AsyncQueryExample
  9. {
  10. static void Main()
  11. {
  12. IntPtr conn = GetConnection();
  13. try
  14. {
  15. QueryAsyncCallback queryAsyncCallback = new QueryAsyncCallback(QueryCallback);
  16. TDengine.QueryAsync(conn, "select * from meters", queryAsyncCallback, IntPtr.Zero);
  17. Thread.Sleep(2000);
  18. }
  19. finally
  20. {
  21. TDengine.Close(conn);
  22. }
  23. }
  24. static void QueryCallback(IntPtr param, IntPtr taosRes, int code)
  25. {
  26. if (code == 0 && taosRes != IntPtr.Zero)
  27. {
  28. FetchRawBlockAsyncCallback fetchRowAsyncCallback = new FetchRawBlockAsyncCallback(FetchRawBlockCallback);
  29. TDengine.FetchRawBlockAsync(taosRes, fetchRowAsyncCallback, param);
  30. }
  31. else
  32. {
  33. throw new Exception($"async query data failed,code:{code},reason:{TDengine.Error(taosRes)}");
  34. }
  35. }
  36. // Iteratively call this interface until "numOfRows" is no greater than 0.
  37. static void FetchRawBlockCallback(IntPtr param, IntPtr taosRes, int numOfRows)
  38. {
  39. if (numOfRows > 0)
  40. {
  41. Console.WriteLine($"{numOfRows} rows async retrieved");
  42. IntPtr pdata = TDengine.GetRawBlock(taosRes);
  43. List<TDengineMeta> metaList = TDengine.FetchFields(taosRes);
  44. List<object> dataList = LibTaos.ReadRawBlock(pdata, metaList, numOfRows);
  45. for (int i = 0; i < dataList.Count; i++)
  46. {
  47. if (i != 0 && (i + 1) % metaList.Count == 0)
  48. {
  49. Console.WriteLine("{0}\t|", dataList[i]);
  50. }
  51. else
  52. {
  53. Console.Write("{0}\t|", dataList[i]);
  54. }
  55. }
  56. Console.WriteLine("");
  57. TDengine.FetchRawBlockAsync(taosRes, FetchRawBlockCallback, param);
  58. }
  59. else
  60. {
  61. if (numOfRows == 0)
  62. {
  63. Console.WriteLine("async retrieve complete.");
  64. }
  65. else
  66. {
  67. throw new Exception($"FetchRawBlockCallback callback error, error code {numOfRows}");
  68. }
  69. TDengine.FreeResult(taosRes);
  70. }
  71. }
  72. static IntPtr GetConnection()
  73. {
  74. string host = "localhost";
  75. short port = 6030;
  76. string username = "root";
  77. string password = "taosdata";
  78. string dbname = "power";
  79. var conn = TDengine.Connect(host, username, password, dbname, port);
  80. if (conn == IntPtr.Zero)
  81. {
  82. throw new Exception("Connect to TDengine failed");
  83. }
  84. else
  85. {
  86. Console.WriteLine("Connect to TDengine success");
  87. }
  88. return conn;
  89. }
  90. }
  91. }
  92. // //output:
  93. // // Connect to TDengine success
  94. // // 8 rows async retrieved
  95. // // 1538548685500 | 11.8 | 221 | 0.28 | california.losangeles | 2 |
  96. // // 1538548696600 | 13.4 | 223 | 0.29 | california.losangeles | 2 |
  97. // // 1538548685000 | 10.8 | 223 | 0.29 | california.losangeles | 3 |
  98. // // 1538548686500 | 11.5 | 221 | 0.35 | california.losangeles | 3 |
  99. // // 1538548685000 | 10.3 | 219 | 0.31 | california.sanfrancisco | 2 |
  100. // // 1538548695000 | 12.6 | 218 | 0.33 | california.sanfrancisco | 2 |
  101. // // 1538548696800 | 12.3 | 221 | 0.31 | california.sanfrancisco | 2 |
  102. // // 1538548696650 | 10.3 | 218 | 0.25 | california.sanfrancisco | 3 |
  103. // // async retrieve complete.

查看源码

更多示例程序

示例程序示例程序描述
CURD使用 TDengine.Connector 实现的建表、插入、查询示例
JSON Tag使用 TDengine.Connector 实现的写入和查询 JSON tag 类型数据的示例
stmt使用 TDengine.Connector 实现的参数绑定插入和查询的示例
schemaless使用 TDengine.Connector 实现的使用 schemaless 写入的示例
async query使用 TDengine.Connector 实现的异步查询的示例
数据订阅(TMQ)使用 TDengine.Connector 实现的订阅数据的示例
Basic WebSocket Usage使用 TDengine.Connector 的 WebSocket 基本的示例
Basic WebSocket STMT使用 TDengine.Connector 的 WebSocket STMT 基本的示例

重要更新记录

TDengine.Connector说明
3.0.2支持 .NET Framework 4.5 及以上,支持 .NET standard 2.0。Nuget Package 包含 WebSocket 动态库。
3.0.1支持 WebSocket 和 Cloud,查询,插入,参数绑定。
3.0.0支持 TDengine 3.0.0.0,不兼容 2.x。新增接口TDengine.Impl.GetData(),解析查询结果。
1.0.7修复 TDengine.Query()内存泄露。
1.0.6修复 schemaless 在 1.0.4 和 1.0.5 中失效 bug。
1.0.5修复 Windows 同步查询中文报错 bug。
1.0.4新增异步查询,订阅等功能。修复绑定参数 bug。
1.0.3新增参数绑定、schemaless、 json tag等功能。
1.0.2新增连接管理、同步查询、错误信息等功能。

其他说明

第三方驱动

IoTSharp.Data.Taos 是一个 TDengine 的 ADO.NET 连接器,其中包含了用于EntityFrameworkCore 的提供程序 IoTSharp.EntityFrameworkCore.Taos 和健康检查组件 IoTSharp.HealthChecks.Taos ,支持 Linux,Windows 平台。该连接器由社区贡献者麦壳饼@@maikebing 提供,具体请参考:

常见问题

  1. “Unable to establish connection”,”Unable to resolve FQDN”

    一般是因为 FQDN 配置不正确。可以参考如何彻底搞懂 TDengine 的 FQDN解决。

  2. Unhandled exception. System.DllNotFoundException: Unable to load DLL ‘taos’ or one of its dependencies: 找不到指定的模块。

    一般是因为程序没有找到依赖的客户端驱动。解决方法为:Windows 下可以将 C:\TDengine\driver\taos.dll 拷贝到 C:\Windows\System32\ 目录下,Linux 下建立如下软链接 ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so 即可。

API 参考

API 参考