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 连接
-
连接管理
- 普通查询
- 连续查询
- 参数绑定
- 数据订阅(TMQ)
- Schemaless
- 连接管理
- 普通查询
- 连续查询
- 参数绑定
安装步骤
安装前准备
安装 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;
3. namespace TDengineExample
4. {
6. internal class EstablishConnection
7. {
8. static void Main(String[] args)
9. {
10. string host = "localhost";
11. short port = 6030;
12. string username = "root";
13. string password = "taosdata";
14. string dbname = "";
16. var conn = TDengine.Connect(host, username, password, dbname, port);
17. if (conn == IntPtr.Zero)
18. {
19. Console.WriteLine("Connect to TDengine failed");
20. }
21. else
22. {
23. Console.WriteLine("Connect to TDengine success");
24. }
25. TDengine.Close(conn);
26. TDengine.Cleanup();
27. }
28. }
29. }
使用 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;
4. namespace Examples
5. {
6. public class WSConnExample
7. {
8. static int Main(string[] args)
9. {
10. string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
11. 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. // close connection.
22. LibTaosWS.WSClose(wsConn);
23. }
25. return 0;
26. }
27. }
28. }
使用示例
写入数据
SQL 写入
- 原生连接
- WebSocket 连接
1. using TDengineDriver;
4. namespace TDengineExample
5. {
6. internal class SQLInsertExample
7. {
9. static void Main()
10. {
11. IntPtr conn = GetConnection();
12. try
13. {
14. IntPtr res = TDengine.Query(conn, "CREATE DATABASE power");
15. CheckRes(conn, res, "failed to create database");
16. res = TDengine.Query(conn, "USE power");
17. CheckRes(conn, res, "failed to change database");
18. res = TDengine.Query(conn, "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)");
19. CheckRes(conn, res, "failed to create stable");
20. 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) " +
21. "d1002 USING power.meters TAGS('California.SanFrancisco', 3) VALUES('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000) " +
22. "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) " +
23. "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)";
24. res = TDengine.Query(conn, sql);
25. CheckRes(conn, res, "failed to insert data");
26. int affectedRows = TDengine.AffectRows(res);
27. Console.WriteLine("affectedRows " + affectedRows);
28. TDengine.FreeResult(res);
29. }
30. finally
31. {
32. TDengine.Close(conn);
33. }
35. }
37. static IntPtr GetConnection()
38. {
39. string host = "localhost";
40. short port = 6030;
41. string username = "root";
42. string password = "taosdata";
43. string dbname = "";
44. var conn = TDengine.Connect(host, username, password, dbname, port);
45. if (conn == IntPtr.Zero)
46. {
47. throw new Exception("Connect to TDengine failed");
48. }
49. else
50. {
51. Console.WriteLine("Connect to TDengine success");
52. }
53. return conn;
54. }
56. static void CheckRes(IntPtr conn, IntPtr res, String errorMsg)
57. {
58. if (TDengine.ErrorNo(res) != 0)
59. {
60. throw new Exception($"{errorMsg} since: {TDengine.Error(res)}");
61. }
62. }
64. }
65. }
67. // output:
68. // Connect to TDengine success
69. // affectedRows 8
1. using System;
2. using TDengineWS.Impl;
4. namespace Examples
5. {
6. public class WSInsertExample
7. {
8. static int Main(string[] args)
9. {
10. string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
11. IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
13. // Assert if connection is validate
14. if (wsConn == IntPtr.Zero)
15. {
16. Console.WriteLine("get WS connection failed");
17. return -1;
18. }
19. else
20. {
21. Console.WriteLine("Establish connect success.");
22. }
24. string createTable = "CREATE STABLE test.meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);";
25. 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)" +
26. "test.d1002 USING test.meters TAGS('California.SanFrancisco', 3) VALUES('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)" +
27. "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) " +
28. "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)";
30. IntPtr wsRes = LibTaosWS.WSQuery(wsConn, createTable);
31. ValidInsert("create table", wsRes);
32. LibTaosWS.WSFreeResult(wsRes);
34. wsRes = LibTaosWS.WSQuery(wsConn, insert);
35. ValidInsert("insert data", wsRes);
36. LibTaosWS.WSFreeResult(wsRes);
38. // close connection.
39. LibTaosWS.WSClose(wsConn);
41. return 0;
42. }
44. static void ValidInsert(string desc, IntPtr wsRes)
45. {
46. int code = LibTaosWS.WSErrorNo(wsRes);
47. if (code != 0)
48. {
49. Console.WriteLine($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}");
50. }
51. else
52. {
53. Console.WriteLine("{0} success affect {2} rows, cost {1} nanoseconds", desc, LibTaosWS.WSTakeTiming(wsRes), LibTaosWS.WSAffectRows(wsRes));
54. }
55. }
56. }
58. }
59. // Establish connect success.
60. // create table success affect 0 rows, cost 3717542 nanoseconds
61. // insert data success affect 8 rows, cost 2613637 nanoseconds
InfluxDB 行协议写入
1. using TDengineDriver;
3. namespace TDengineExample
4. {
5. internal class InfluxDBLineExample
6. {
7. static void Main()
8. {
9. IntPtr conn = GetConnection();
10. PrepareDatabase(conn);
11. string[] lines = {
12. "meters,location=California.LosAngeles,groupid=2 current=11.8,voltage=221,phase=0.28 1648432611249",
13. "meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0.29 1648432611250",
14. "meters,location=California.LosAngeles,groupid=3 current=10.8,voltage=223,phase=0.29 1648432611249",
15. "meters,location=California.LosAngeles,groupid=3 current=11.3,voltage=221,phase=0.35 1648432611250"
16. };
17. IntPtr res = TDengine.SchemalessInsert(conn, lines, lines.Length, (int)TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS);
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);
29. }
30. static IntPtr GetConnection()
31. {
32. string host = "localhost";
33. short port = 6030;
34. string username = "root";
35. string password = "taosdata";
36. string dbname = "";
37. var conn = TDengine.Connect(host, username, password, dbname, port);
38. if (conn == IntPtr.Zero)
39. {
40. throw new Exception("Connect to TDengine failed");
41. }
42. else
43. {
44. Console.WriteLine("Connect to TDengine success");
45. }
46. return conn;
47. }
49. static void PrepareDatabase(IntPtr conn)
50. {
51. IntPtr res = TDengine.Query(conn, "CREATE DATABASE test");
52. if (TDengine.ErrorNo(res) != 0)
53. {
54. throw new Exception("failed to create database, reason: " + TDengine.Error(res));
55. }
56. res = TDengine.Query(conn, "USE test");
57. if (TDengine.ErrorNo(res) != 0)
58. {
59. throw new Exception("failed to change database, reason: " + TDengine.Error(res));
60. }
61. }
63. }
65. }
OpenTSDB Telnet 行协议写入
1. using TDengineDriver;
3. namespace TDengineExample
4. {
5. internal class OptsTelnetExample
6. {
7. static void Main()
8. {
9. IntPtr conn = GetConnection();
10. try
11. {
12. PrepareDatabase(conn);
13. string[] lines = {
14. "meters.current 1648432611249 10.3 location=California.SanFrancisco groupid=2",
15. "meters.current 1648432611250 12.6 location=California.SanFrancisco groupid=2",
16. "meters.current 1648432611249 10.8 location=California.LosAngeles groupid=3",
17. "meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3",
18. "meters.voltage 1648432611249 219 location=California.SanFrancisco groupid=2",
19. "meters.voltage 1648432611250 218 location=California.SanFrancisco groupid=2",
20. "meters.voltage 1648432611249 221 location=California.LosAngeles groupid=3",
21. "meters.voltage 1648432611250 217 location=California.LosAngeles groupid=3",
22. };
23. IntPtr res = TDengine.SchemalessInsert(conn, lines, lines.Length, (int)TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED);
24. if (TDengine.ErrorNo(res) != 0)
25. {
26. throw new Exception("SchemalessInsert failed since " + TDengine.Error(res));
27. }
28. else
29. {
30. int affectedRows = TDengine.AffectRows(res);
31. Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows");
32. }
33. TDengine.FreeResult(res);
34. }
35. catch
36. {
37. TDengine.Close(conn);
38. }
39. }
40. static IntPtr GetConnection()
41. {
42. string host = "localhost";
43. short port = 6030;
44. string username = "root";
45. string password = "taosdata";
46. string dbname = "";
47. var conn = TDengine.Connect(host, username, password, dbname, port);
48. if (conn == IntPtr.Zero)
49. {
50. throw new Exception("Connect to TDengine failed");
51. }
52. else
53. {
54. Console.WriteLine("Connect to TDengine success");
55. }
56. return conn;
57. }
59. static void PrepareDatabase(IntPtr conn)
60. {
61. IntPtr res = TDengine.Query(conn, "CREATE DATABASE test");
62. if (TDengine.ErrorNo(res) != 0)
63. {
64. throw new Exception("failed to create database, reason: " + TDengine.Error(res));
65. }
66. res = TDengine.Query(conn, "USE test");
67. if (TDengine.ErrorNo(res) != 0)
68. {
69. throw new Exception("failed to change database, reason: " + TDengine.Error(res));
70. }
71. }
72. }
73. }
OpenTSDB JSON 行协议写入
1. using TDengineDriver;
3. namespace TDengineExample
4. {
5. internal class OptsJsonExample
6. {
7. static void Main()
8. {
9. IntPtr conn = GetConnection();
10. try
11. {
12. PrepareDatabase(conn);
13. string[] lines = { "[{\"metric\": \"meters.current\", \"timestamp\": 1648432611249, \"value\": 10.3, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," +
14. " {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611249, \"value\": 219, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}, " +
15. "{\"metric\": \"meters.current\", \"timestamp\": 1648432611250, \"value\": 12.6, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," +
16. " {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611250, \"value\": 221, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}]"
17. };
19. IntPtr res = TDengine.SchemalessInsert(conn, lines, 1, (int)TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED);
20. if (TDengine.ErrorNo(res) != 0)
21. {
22. throw new Exception("SchemalessInsert failed since " + TDengine.Error(res));
23. }
24. else
25. {
26. int affectedRows = TDengine.AffectRows(res);
27. Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows");
28. }
29. TDengine.FreeResult(res);
30. }
31. finally
32. {
33. TDengine.Close(conn);
34. }
35. }
36. static IntPtr GetConnection()
37. {
38. string host = "localhost";
39. short port = 6030;
40. string username = "root";
41. string password = "taosdata";
42. string dbname = "";
43. var conn = TDengine.Connect(host, username, password, dbname, port);
44. if (conn == IntPtr.Zero)
45. {
46. throw new Exception("Connect to TDengine failed");
47. }
48. else
49. {
50. Console.WriteLine("Connect to TDengine success");
51. }
52. return conn;
53. }
55. static void PrepareDatabase(IntPtr conn)
56. {
57. IntPtr res = TDengine.Query(conn, "CREATE DATABASE test");
58. if (TDengine.ErrorNo(res) != 0)
59. {
60. throw new Exception("failed to create database, reason: " + TDengine.Error(res));
61. }
62. res = TDengine.Query(conn, "USE test");
63. if (TDengine.ErrorNo(res) != 0)
64. {
65. throw new Exception("failed to change database, reason: " + TDengine.Error(res));
66. }
67. }
68. }
69. }
参数绑定
- 原生连接
- WebSocket 连接
1. using TDengineDriver;
3. namespace TDengineExample
4. {
5. internal class StmtInsertExample
6. {
7. private static IntPtr conn;
8. private static IntPtr stmt;
9. static void Main()
10. {
11. conn = GetConnection();
12. try
13. {
14. PrepareSTable();
15. // 1. init and prepare
16. stmt = TDengine.StmtInit(conn);
17. if (stmt == IntPtr.Zero)
18. {
19. throw new Exception("failed to init stmt.");
20. }
21. int res = TDengine.StmtPrepare(stmt, "INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)");
22. CheckStmtRes(res, "failed to prepare stmt");
24. // 2. bind table name and tags
25. TAOS_MULTI_BIND[] tags = new TAOS_MULTI_BIND[2] { TaosMultiBind.MultiBindBinary(new string[] { "California.SanFrancisco" }), TaosMultiBind.MultiBindInt(new int?[] { 2 }) };
26. res = TDengine.StmtSetTbnameTags(stmt, "d1001", tags);
27. CheckStmtRes(res, "failed to bind table name and tags");
29. // 3. bind values
30. TAOS_MULTI_BIND[] values = new TAOS_MULTI_BIND[4] {
31. TaosMultiBind.MultiBindTimestamp(new long[2] { 1648432611249, 1648432611749}),
32. TaosMultiBind.MultiBindFloat(new float?[2] { 10.3f, 12.6f}),
33. TaosMultiBind.MultiBindInt(new int?[2] { 219, 218}),
34. TaosMultiBind.MultiBindFloat(new float?[2]{ 0.31f, 0.33f})
35. };
36. res = TDengine.StmtBindParamBatch(stmt, values);
37. CheckStmtRes(res, "failed to bind params");
39. // 4. add batch
40. res = TDengine.StmtAddBatch(stmt);
41. CheckStmtRes(res, "failed to add batch");
43. // 5. execute
44. res = TDengine.StmtExecute(stmt);
45. CheckStmtRes(res, "failed to execute");
47. // 6. free
48. TaosMultiBind.FreeTaosBind(tags);
49. TaosMultiBind.FreeTaosBind(values);
50. }
51. finally
52. {
53. TDengine.Close(conn);
54. }
56. }
58. static IntPtr GetConnection()
59. {
60. string host = "localhost";
61. short port = 6030;
62. string username = "root";
63. string password = "taosdata";
64. string dbname = "";
65. var conn = TDengine.Connect(host, username, password, dbname, port);
66. if (conn == IntPtr.Zero)
67. {
68. throw new Exception("Connect to TDengine failed");
69. }
70. else
71. {
72. Console.WriteLine("Connect to TDengine success");
73. }
74. return conn;
75. }
77. static void PrepareSTable()
78. {
79. IntPtr res = TDengine.Query(conn, "CREATE DATABASE power");
80. CheckResPtr(res, "failed to create database");
81. res = TDengine.Query(conn, "USE power");
82. CheckResPtr(res, "failed to change database");
83. res = TDengine.Query(conn, "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)");
84. CheckResPtr(res, "failed to create stable");
85. }
87. static void CheckStmtRes(int res, string errorMsg)
88. {
89. if (res != 0)
90. {
91. Console.WriteLine(errorMsg + ", " + TDengine.StmtErrorStr(stmt));
92. int code = TDengine.StmtClose(stmt);
93. if (code != 0)
94. {
95. throw new Exception($"failed to close stmt, {code} reason: {TDengine.StmtErrorStr(stmt)} ");
96. }
97. }
98. }
100. static void CheckResPtr(IntPtr res, string errorMsg)
101. {
102. if (TDengine.ErrorNo(res) != 0)
103. {
104. throw new Exception(errorMsg + " since:" + TDengine.Error(res));
105. }
106. }
108. }
109. }
1. using System;
2. using TDengineWS.Impl;
3. using TDengineDriver;
4. using System.Runtime.InteropServices;
6. namespace Examples
7. {
8. public class WSStmtExample
9. {
10. static int Main(string[] args)
11. {
12. const string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
13. const string table = "meters";
14. const string database = "test";
15. const string childTable = "d1005";
16. string insert = $"insert into ? using {database}.{table} tags(?,?) values(?,?,?,?)";
17. const int numOfTags = 2;
18. const int numOfColumns = 4;
20. // Establish connection
21. IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
22. if (wsConn == IntPtr.Zero)
23. {
24. Console.WriteLine($"get WS connection failed");
25. return -1;
26. }
27. else
28. {
29. Console.WriteLine("Establish connect success...");
30. }
32. // init stmt
33. IntPtr wsStmt = LibTaosWS.WSStmtInit(wsConn);
34. if (wsStmt != IntPtr.Zero)
35. {
36. int code = LibTaosWS.WSStmtPrepare(wsStmt, insert);
37. ValidStmtStep(code, wsStmt, "WSStmtPrepare");
39. TAOS_MULTI_BIND[] wsTags = new TAOS_MULTI_BIND[] { WSMultiBind.WSBindNchar(new string[] { "California.SanDiego" }), WSMultiBind.WSBindInt(new int?[] { 4 }) };
40. code = LibTaosWS.WSStmtSetTbnameTags(wsStmt, $"{database}.{childTable}", wsTags, numOfTags);
41. ValidStmtStep(code, wsStmt, "WSStmtSetTbnameTags");
43. TAOS_MULTI_BIND[] data = new TAOS_MULTI_BIND[4];
44. data[0] = WSMultiBind.WSBindTimestamp(new long[] { 1538548687000, 1538548688000, 1538548689000, 1538548690000, 1538548691000 });
45. data[1] = WSMultiBind.WSBindFloat(new float?[] { 10.30F, 10.40F, 10.50F, 10.60F, 10.70F });
46. data[2] = WSMultiBind.WSBindInt(new int?[] { 223, 221, 222, 220, 219 });
47. data[3] = WSMultiBind.WSBindFloat(new float?[] { 0.31F, 0.32F, 0.33F, 0.35F, 0.28F });
48. code = LibTaosWS.WSStmtBindParamBatch(wsStmt, data, numOfColumns);
49. ValidStmtStep(code, wsStmt, "WSStmtBindParamBatch");
51. code = LibTaosWS.WSStmtAddBatch(wsStmt);
52. ValidStmtStep(code, wsStmt, "WSStmtAddBatch");
54. IntPtr stmtAffectRowPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)));
55. code = LibTaosWS.WSStmtExecute(wsStmt, stmtAffectRowPtr);
56. ValidStmtStep(code, wsStmt, "WSStmtExecute");
57. Console.WriteLine("WS STMT insert {0} rows...", Marshal.ReadInt32(stmtAffectRowPtr));
58. Marshal.FreeHGlobal(stmtAffectRowPtr);
60. LibTaosWS.WSStmtClose(wsStmt);
62. // Free unmanaged memory
63. WSMultiBind.WSFreeTaosBind(wsTags);
64. WSMultiBind.WSFreeTaosBind(data);
66. //check result with SQL "SELECT * FROM test.d1005;"
67. }
68. else
69. {
70. Console.WriteLine("Init STMT failed...");
71. }
73. // close connection.
74. LibTaosWS.WSClose(wsConn);
76. return 0;
77. }
79. static void ValidStmtStep(int code, IntPtr wsStmt, string desc)
80. {
81. if (code != 0)
82. {
83. Console.WriteLine($"{desc} failed,reason: {LibTaosWS.WSErrorStr(wsStmt)}, code: {code}");
84. }
85. else
86. {
87. Console.WriteLine("{0} success...", desc);
88. }
89. }
90. }
91. }
93. // WSStmtPrepare success...
94. // WSStmtSetTbnameTags success...
95. // WSStmtBindParamBatch success...
96. // WSStmtAddBatch success...
97. // WSStmtExecute success...
98. // WS STMT insert 5 rows...
查询数据
同步查询
- 原生连接
- WebSocket 连接
1. using TDengineDriver;
2. using TDengineDriver.Impl;
3. using System.Runtime.InteropServices;
5. namespace TDengineExample
6. {
7. internal class QueryExample
8. {
9. static void Main()
10. {
11. IntPtr conn = GetConnection();
12. try
13. {
14. // run query
15. IntPtr res = TDengine.Query(conn, "SELECT * FROM meters LIMIT 2");
16. if (TDengine.ErrorNo(res) != 0)
17. {
18. throw new Exception("Failed to query since: " + TDengine.Error(res));
19. }
21. // get filed count
22. int fieldCount = TDengine.FieldCount(res);
23. Console.WriteLine("fieldCount=" + fieldCount);
25. // print column names
26. List<TDengineMeta> metas = LibTaos.GetMeta(res);
27. for (int i = 0; i < metas.Count; i++)
28. {
29. Console.Write(metas[i].name + "\t");
30. }
31. Console.WriteLine();
33. // print values
34. List<Object> resData = LibTaos.GetData(res);
35. for (int i = 0; i < resData.Count; i++)
36. {
37. Console.Write($"|{resData[i].ToString()} \t");
38. if (((i + 1) % metas.Count == 0))
39. {
40. Console.WriteLine("");
41. }
42. }
43. Console.WriteLine();
45. // Free result after use
46. TDengine.FreeResult(res);
47. }
48. finally
49. {
50. TDengine.Close(conn);
51. }
53. }
54. static IntPtr GetConnection()
55. {
56. string host = "localhost";
57. short port = 6030;
58. string username = "root";
59. string password = "taosdata";
60. string dbname = "power";
61. var conn = TDengine.Connect(host, username, password, dbname, port);
62. if (conn == IntPtr.Zero)
63. {
64. throw new Exception("Connect to TDengine failed");
65. }
66. else
67. {
68. Console.WriteLine("Connect to TDengine success");
69. }
70. return conn;
71. }
72. }
73. }
75. // output:
76. // Connect to TDengine success
77. // fieldCount=6
78. // ts current voltage phase location groupid
79. // 1648432611249 10.3 219 0.31 California.SanFrancisco 2
80. // 1648432611749 12.6 218 0.33 California.SanFrancisco 2
1. using System;
2. using TDengineWS.Impl;
3. using System.Collections.Generic;
4. using TDengineDriver;
6. namespace Examples
7. {
8. public class WSQueryExample
9. {
10. static int Main(string[] args)
11. {
12. string DSN = "ws://root:taosdata@127.0.0.1:6041/test";
13. IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN);
14. if (wsConn == IntPtr.Zero)
15. {
16. Console.WriteLine("get WS connection failed");
17. return -1;
18. }
19. else
20. {
21. Console.WriteLine("Establish connect success.");
22. }
24. string select = "select * from test.meters";
26. // optional:wsRes = LibTaosWS.WSQuery(wsConn, select);
27. IntPtr wsRes = LibTaosWS.WSQueryTimeout(wsConn, select, 1);
28. // Assert if query execute success.
29. int code = LibTaosWS.WSErrorNo(wsRes);
30. if (code != 0)
31. {
32. Console.WriteLine($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}");
33. LibTaosWS.WSFreeResult(wsRes);
34. return -1;
35. }
37. // get meta data
38. List<TDengineMeta> metas = LibTaosWS.WSGetFields(wsRes);
39. // get retrieved data
40. List<object> dataSet = LibTaosWS.WSGetData(wsRes);
42. // do something with result.
43. foreach (var meta in metas)
44. {
45. Console.Write("{0} {1}({2}) \t|\t", meta.name, meta.TypeName(), meta.size);
46. }
47. Console.WriteLine("");
49. for (int i = 0; i < dataSet.Count;)
50. {
51. for (int j = 0; j < metas.Count; j++)
52. {
53. Console.Write("{0}\t|\t", dataSet[i]);
54. i++;
55. }
56. Console.WriteLine("");
57. }
59. // Free result after use.
60. LibTaosWS.WSFreeResult(wsRes);
62. // close connection.
63. LibTaosWS.WSClose(wsConn);
65. return 0;
66. }
67. }
68. }
70. // Establish connect success.
71. // ts TIMESTAMP(8) | current FLOAT(4) | voltage INT(4) | phase FLOAT(4) | location BINARY(64) | groupid INT(4) |
72. // 1538548685000 | 10.8 | 223 | 0.29 | California.LosAngeles | 3 |
73. // 1538548686500 | 11.5 | 221 | 0.35 | California.LosAngeles | 3 |
74. // 1538548685500 | 11.8 | 221 | 0.28 | California.LosAngeles | 2 |
75. // 1538548696600 | 13.4 | 223 | 0.29 | California.LosAngeles | 2 |
76. // 1538548685000 | 10.3 | 219 | 0.31 | California.SanFrancisco | 2 |
77. // 1538548695000 | 12.6 | 218 | 0.33 | California.SanFrancisco | 2 |
78. // 1538548696800 | 12.3 | 221 | 0.31 | California.SanFrancisco | 2 |
79. // 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;
7. namespace TDengineExample
8. {
9. public class AsyncQueryExample
10. {
11. static void Main()
12. {
13. IntPtr conn = GetConnection();
14. try
15. {
16. QueryAsyncCallback queryAsyncCallback = new QueryAsyncCallback(QueryCallback);
17. TDengine.QueryAsync(conn, "select * from meters", queryAsyncCallback, IntPtr.Zero);
18. Thread.Sleep(2000);
19. }
20. finally
21. {
22. TDengine.Close(conn);
23. }
25. }
27. static void QueryCallback(IntPtr param, IntPtr taosRes, int code)
28. {
29. if (code == 0 && taosRes != IntPtr.Zero)
30. {
31. FetchRawBlockAsyncCallback fetchRowAsyncCallback = new FetchRawBlockAsyncCallback(FetchRawBlockCallback);
32. TDengine.FetchRawBlockAsync(taosRes, fetchRowAsyncCallback, param);
33. }
34. else
35. {
36. throw new Exception($"async query data failed,code:{code},reason:{TDengine.Error(taosRes)}");
37. }
38. }
40. // Iteratively call this interface until "numOfRows" is no greater than 0.
41. static void FetchRawBlockCallback(IntPtr param, IntPtr taosRes, int numOfRows)
42. {
43. if (numOfRows > 0)
44. {
45. Console.WriteLine($"{numOfRows} rows async retrieved");
46. IntPtr pdata = TDengine.GetRawBlock(taosRes);
47. List<TDengineMeta> metaList = TDengine.FetchFields(taosRes);
48. List<object> dataList = LibTaos.ReadRawBlock(pdata, metaList, numOfRows);
50. for (int i = 0; i < dataList.Count; i++)
51. {
52. if (i != 0 && (i + 1) % metaList.Count == 0)
53. {
54. Console.WriteLine("{0}\t|", dataList[i]);
55. }
56. else
57. {
58. Console.Write("{0}\t|", dataList[i]);
59. }
60. }
61. Console.WriteLine("");
62. TDengine.FetchRawBlockAsync(taosRes, FetchRawBlockCallback, param);
63. }
64. else
65. {
66. if (numOfRows == 0)
67. {
68. Console.WriteLine("async retrieve complete.");
69. }
70. else
71. {
72. throw new Exception($"FetchRawBlockCallback callback error, error code {numOfRows}");
73. }
74. TDengine.FreeResult(taosRes);
75. }
76. }
78. static IntPtr GetConnection()
79. {
80. string host = "localhost";
81. short port = 6030;
82. string username = "root";
83. string password = "taosdata";
84. string dbname = "power";
85. var conn = TDengine.Connect(host, username, password, dbname, port);
86. if (conn == IntPtr.Zero)
87. {
88. throw new Exception("Connect to TDengine failed");
89. }
90. else
91. {
92. Console.WriteLine("Connect to TDengine success");
93. }
94. return conn;
95. }
96. }
97. }
99. // //output:
100. // // Connect to TDengine success
101. // // 8 rows async retrieved
103. // // 1538548685500 | 11.8 | 221 | 0.28 | california.losangeles | 2 |
104. // // 1538548696600 | 13.4 | 223 | 0.29 | california.losangeles | 2 |
105. // // 1538548685000 | 10.8 | 223 | 0.29 | california.losangeles | 3 |
106. // // 1538548686500 | 11.5 | 221 | 0.35 | california.losangeles | 3 |
107. // // 1538548685000 | 10.3 | 219 | 0.31 | california.sanfrancisco | 2 |
108. // // 1538548695000 | 12.6 | 218 | 0.33 | california.sanfrancisco | 2 |
109. // // 1538548696800 | 12.3 | 221 | 0.31 | california.sanfrancisco | 2 |
110. // // 1538548696650 | 10.3 | 218 | 0.25 | california.sanfrancisco | 3 |
111. // // 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 提供,具体请参考:
- 接口下载: <https://github.com/IoTSharp/EntityFrameworkCore.Taos>
- 用法说明:<https://www.taosdata.com/blog/2020/11/02/1901.html>
常见问题
- “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 即可。
