C# Connector

TDengine.Connector is a C# language connector provided by TDengine that allows C# developers to develop C# applications that access TDengine cluster data.

The TDengine.Connector connector supports connect to TDengine instances via the TDengine client driver (taosc), providing data writing, querying, subscription, schemaless writing, bind interface, etc. The TDengine.Connector currently does not provide a REST connection interface. Developers can write their RESTful application by referring to the REST API documentation.

This article describes how to install TDengine.Connector in a Linux or Windows environment and connect to TDengine clusters via TDengine.Connector to perform basic operations such as data writing and querying.

The source code of TDengine.Connector is hosted on GitHub.

Supported Platforms

The supported platforms are the same as those supported by the TDengine client driver.

Version support

Please refer to version support list

Supported features

  1. Connection Management
  2. General Query
  3. Continuous Query
  4. Parameter Binding
  5. Subscription
  6. Schemaless

Installation Steps

Pre-installation preparation

Install via dotnet CLI

  • Get C# driver using dotnet CLI
  • Use source code to get C# driver

You can reference the TDengine.Connector published in Nuget to the current project via the dotnet command under the path of the existing .NET project.

  1. dotnet add package TDengine.Connector

You can download TDengine’s source code and directly reference the latest version of the TDengine.Connector library

  1. git clone https://github.com/taosdata/TDengine.git
  2. cd TDengine/src/connector/C#/src/
  3. cp -r TDengineDriver/ myProject
  4. cd myProject
  5. dotnet add TDengineDriver/TDengineDriver.csproj

Create a connection

  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. }

Usage examples

Write data

SQL Write

  1. using TDengineDriver;
  2. namespace TDengineExample
  3. {
  4. internal class SQLInsertExample
  5. {
  6. static void Main()
  7. {
  8. IntPtr conn = GetConnection();
  9. IntPtr res = TDengine.Query(conn, "CREATE DATABASE power");
  10. CheckRes(conn, res, "failed to create database");
  11. res = TDengine.Query(conn, "USE power");
  12. CheckRes(conn, res, "failed to change database");
  13. res = TDengine.Query(conn, "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)");
  14. CheckRes(conn, res, "failed to create stable");
  15. 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) " +
  16. "d1002 USING power.meters TAGS(California.SanFrancisco, 3) VALUES('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000) " +
  17. "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) " +
  18. "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)";
  19. res = TDengine.Query(conn, sql);
  20. CheckRes(conn, res, "failed to insert data");
  21. int affectedRows = TDengine.AffectRows(res);
  22. Console.WriteLine("affectedRows " + affectedRows);
  23. ExitProgram(conn, 0);
  24. }
  25. static IntPtr GetConnection()
  26. {
  27. string host = "localhost";
  28. short port = 6030;
  29. string username = "root";
  30. string password = "taosdata";
  31. string dbname = "";
  32. var conn = TDengine.Connect(host, username, password, dbname, port);
  33. if (conn == IntPtr.Zero)
  34. {
  35. Console.WriteLine("Connect to TDengine failed");
  36. Environment.Exit(0);
  37. }
  38. else
  39. {
  40. Console.WriteLine("Connect to TDengine success");
  41. }
  42. return conn;
  43. }
  44. static void CheckRes(IntPtr conn, IntPtr res, String errorMsg)
  45. {
  46. if (TDengine.ErrorNo(res) != 0)
  47. {
  48. Console.Write(errorMsg + " since: " + TDengine.Error(res));
  49. ExitProgram(conn, 1);
  50. }
  51. }
  52. static void ExitProgram(IntPtr conn, int exitCode)
  53. {
  54. TDengine.Close(conn);
  55. TDengine.Cleanup();
  56. Environment.Exit(exitCode);
  57. }
  58. }
  59. }
  60. // output:
  61. // Connect to TDengine success
  62. // affectedRows 8

view source code

InfluxDB line protocol write

  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. Console.WriteLine("SchemalessInsert failed since " + TDengine.Error(res));
  20. ExitProgram(conn, 1);
  21. }
  22. else
  23. {
  24. int affectedRows = TDengine.AffectRows(res);
  25. Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows");
  26. }
  27. TDengine.FreeResult(res);
  28. ExitProgram(conn, 0);
  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. Console.WriteLine("Connect to TDengine failed");
  41. TDengine.Cleanup();
  42. Environment.Exit(1);
  43. }
  44. else
  45. {
  46. Console.WriteLine("Connect to TDengine success");
  47. }
  48. return conn;
  49. }
  50. static void PrepareDatabase(IntPtr conn)
  51. {
  52. IntPtr res = TDengine.Query(conn, "CREATE DATABASE test");
  53. if (TDengine.ErrorNo(res) != 0)
  54. {
  55. Console.WriteLine("failed to create database, reason: " + TDengine.Error(res));
  56. ExitProgram(conn, 1);
  57. }
  58. res = TDengine.Query(conn, "USE test");
  59. if (TDengine.ErrorNo(res) != 0)
  60. {
  61. Console.WriteLine("failed to change database, reason: " + TDengine.Error(res));
  62. ExitProgram(conn, 1);
  63. }
  64. }
  65. static void ExitProgram(IntPtr conn, int exitCode)
  66. {
  67. TDengine.Close(conn);
  68. TDengine.Cleanup();
  69. Environment.Exit(exitCode);
  70. }
  71. }
  72. }

view source code

OpenTSDB Telnet line protocol write

  1. using TDengineDriver;
  2. namespace TDengineExample
  3. {
  4. internal class OptsTelnetExample
  5. {
  6. static void Main()
  7. {
  8. IntPtr conn = GetConnection();
  9. PrepareDatabase(conn);
  10. string[] lines = {
  11. "meters.current 1648432611249 10.3 location=California.SanFrancisco groupid=2",
  12. "meters.current 1648432611250 12.6 location=California.SanFrancisco groupid=2",
  13. "meters.current 1648432611249 10.8 location=California.LosAngeles groupid=3",
  14. "meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3",
  15. "meters.voltage 1648432611249 219 location=California.SanFrancisco groupid=2",
  16. "meters.voltage 1648432611250 218 location=California.SanFrancisco groupid=2",
  17. "meters.voltage 1648432611249 221 location=California.LosAngeles groupid=3",
  18. "meters.voltage 1648432611250 217 location=California.LosAngeles groupid=3",
  19. };
  20. IntPtr res = TDengine.SchemalessInsert(conn, lines, lines.Length, (int)TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED);
  21. if (TDengine.ErrorNo(res) != 0)
  22. {
  23. Console.WriteLine("SchemalessInsert failed since " + TDengine.Error(res));
  24. ExitProgram(conn, 1);
  25. }
  26. else
  27. {
  28. int affectedRows = TDengine.AffectRows(res);
  29. Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows");
  30. }
  31. TDengine.FreeResult(res);
  32. ExitProgram(conn, 0);
  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. Console.WriteLine("Connect to TDengine failed");
  45. TDengine.Cleanup();
  46. Environment.Exit(1);
  47. }
  48. else
  49. {
  50. Console.WriteLine("Connect to TDengine success");
  51. }
  52. return conn;
  53. }
  54. static void PrepareDatabase(IntPtr conn)
  55. {
  56. IntPtr res = TDengine.Query(conn, "CREATE DATABASE test");
  57. if (TDengine.ErrorNo(res) != 0)
  58. {
  59. Console.WriteLine("failed to create database, reason: " + TDengine.Error(res));
  60. ExitProgram(conn, 1);
  61. }
  62. res = TDengine.Query(conn, "USE test");
  63. if (TDengine.ErrorNo(res) != 0)
  64. {
  65. Console.WriteLine("failed to change database, reason: " + TDengine.Error(res));
  66. ExitProgram(conn, 1);
  67. }
  68. }
  69. static void ExitProgram(IntPtr conn, int exitCode)
  70. {
  71. TDengine.Close(conn);
  72. TDengine.Cleanup();
  73. Environment.Exit(exitCode);
  74. }
  75. }
  76. }

view source code

OpenTSDB JSON line protocol write

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

view source code

Query data

Synchronous Query

  1. using TDengineDriver;
  2. using System.Runtime.InteropServices;
  3. namespace TDengineExample
  4. {
  5. internal class QueryExample
  6. {
  7. static void Main()
  8. {
  9. IntPtr conn = GetConnection();
  10. // run query
  11. IntPtr res = TDengine.Query(conn, "SELECT * FROM test.meters LIMIT 2");
  12. if (TDengine.ErrorNo(res) != 0)
  13. {
  14. Console.WriteLine("Failed to query since: " + TDengine.Error(res));
  15. TDengine.Close(conn);
  16. TDengine.Cleanup();
  17. return;
  18. }
  19. // get filed count
  20. int fieldCount = TDengine.FieldCount(res);
  21. Console.WriteLine("fieldCount=" + fieldCount);
  22. // print column names
  23. List<TDengineMeta> metas = TDengine.FetchFields(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. IntPtr row;
  31. while ((row = TDengine.FetchRows(res)) != IntPtr.Zero)
  32. {
  33. List<TDengineMeta> metaList = TDengine.FetchFields(res);
  34. int numOfFiled = TDengine.FieldCount(res);
  35. List<String> dataRaw = new List<string>();
  36. IntPtr colLengthPrt = TDengine.FetchLengths(res);
  37. int[] colLengthArr = new int[numOfFiled];
  38. Marshal.Copy(colLengthPrt, colLengthArr, 0, numOfFiled);
  39. for (int i = 0; i < numOfFiled; i++)
  40. {
  41. TDengineMeta meta = metaList[i];
  42. IntPtr data = Marshal.ReadIntPtr(row, IntPtr.Size * i);
  43. if (data == IntPtr.Zero)
  44. {
  45. Console.Write("NULL\t");
  46. continue;
  47. }
  48. switch ((TDengineDataType)meta.type)
  49. {
  50. case TDengineDataType.TSDB_DATA_TYPE_BOOL:
  51. bool v1 = Marshal.ReadByte(data) == 0 ? false : true;
  52. Console.Write(v1.ToString() + "\t");
  53. break;
  54. case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
  55. sbyte v2 = (sbyte)Marshal.ReadByte(data);
  56. Console.Write(v2.ToString() + "\t");
  57. break;
  58. case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
  59. short v3 = Marshal.ReadInt16(data);
  60. Console.Write(v3.ToString() + "\t");
  61. break;
  62. case TDengineDataType.TSDB_DATA_TYPE_INT:
  63. int v4 = Marshal.ReadInt32(data);
  64. Console.Write(v4.ToString() + "\t");
  65. break;
  66. case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
  67. long v5 = Marshal.ReadInt64(data);
  68. Console.Write(v5.ToString() + "\t");
  69. break;
  70. case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
  71. float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
  72. Console.Write(v6.ToString() + "\t");
  73. break;
  74. case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
  75. double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
  76. Console.Write(v7.ToString() + "\t");
  77. break;
  78. case TDengineDataType.TSDB_DATA_TYPE_BINARY:
  79. string v8 = Marshal.PtrToStringUTF8(data, colLengthArr[i]);
  80. Console.Write(v8 + "\t");
  81. break;
  82. case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
  83. long v9 = Marshal.ReadInt64(data);
  84. Console.Write(v9.ToString() + "\t");
  85. break;
  86. case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
  87. string v10 = Marshal.PtrToStringUTF8(data, colLengthArr[i]);
  88. Console.Write(v10 + "\t");
  89. break;
  90. case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
  91. byte v12 = Marshal.ReadByte(data);
  92. Console.Write(v12.ToString() + "\t");
  93. break;
  94. case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
  95. ushort v13 = (ushort)Marshal.ReadInt16(data);
  96. Console.Write(v13.ToString() + "\t");
  97. break;
  98. case TDengineDataType.TSDB_DATA_TYPE_UINT:
  99. uint v14 = (uint)Marshal.ReadInt32(data);
  100. Console.Write(v14.ToString() + "\t");
  101. break;
  102. case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
  103. ulong v15 = (ulong)Marshal.ReadInt64(data);
  104. Console.Write(v15.ToString() + "\t");
  105. break;
  106. case TDengineDataType.TSDB_DATA_TYPE_JSONTAG:
  107. string v16 = Marshal.PtrToStringUTF8(data, colLengthArr[i]);
  108. Console.Write(v16 + "\t");
  109. break;
  110. default:
  111. Console.Write("nonsupport data type value");
  112. break;
  113. }
  114. }
  115. Console.WriteLine();
  116. }
  117. if (TDengine.ErrorNo(res) != 0)
  118. {
  119. Console.WriteLine($"Query is not complete, Error {TDengine.ErrorNo(res)} {TDengine.Error(res)}");
  120. }
  121. // exit
  122. TDengine.FreeResult(res);
  123. TDengine.Close(conn);
  124. TDengine.Cleanup();
  125. }
  126. static IntPtr GetConnection()
  127. {
  128. string host = "localhost";
  129. short port = 6030;
  130. string username = "root";
  131. string password = "taosdata";
  132. string dbname = "power";
  133. var conn = TDengine.Connect(host, username, password, dbname, port);
  134. if (conn == IntPtr.Zero)
  135. {
  136. Console.WriteLine("Connect to TDengine failed");
  137. System.Environment.Exit(0);
  138. }
  139. else
  140. {
  141. Console.WriteLine("Connect to TDengine success");
  142. }
  143. return conn;
  144. }
  145. }
  146. }
  147. // output:
  148. // Connect to TDengine success
  149. // fieldCount=6
  150. // ts current voltage phase location groupid
  151. // 1648432611249 10.3 219 0.31 California.SanFrancisco 2
  152. // 1648432611749 12.6 218 0.33 California.SanFrancisco 2

view source code

Asynchronous query

  1. using TDengineDriver;
  2. using System.Runtime.InteropServices;
  3. namespace TDengineExample
  4. {
  5. public class AsyncQueryExample
  6. {
  7. static void Main()
  8. {
  9. IntPtr conn = GetConnection();
  10. QueryAsyncCallback queryAsyncCallback = new QueryAsyncCallback(QueryCallback);
  11. TDengine.QueryAsync(conn, "select * from meters", queryAsyncCallback, IntPtr.Zero);
  12. Thread.Sleep(2000);
  13. TDengine.Close(conn);
  14. TDengine.Cleanup();
  15. }
  16. static void QueryCallback(IntPtr param, IntPtr taosRes, int code)
  17. {
  18. if (code == 0 && taosRes != IntPtr.Zero)
  19. {
  20. FetchRowAsyncCallback fetchRowAsyncCallback = new FetchRowAsyncCallback(FetchRowCallback);
  21. TDengine.FetchRowAsync(taosRes, fetchRowAsyncCallback, param);
  22. }
  23. else
  24. {
  25. Console.WriteLine($"async query data failed, failed code {code}");
  26. }
  27. }
  28. static void FetchRowCallback(IntPtr param, IntPtr taosRes, int numOfRows)
  29. {
  30. if (numOfRows > 0)
  31. {
  32. Console.WriteLine($"{numOfRows} rows async retrieved");
  33. DisplayRes(taosRes);
  34. TDengine.FetchRowAsync(taosRes, FetchRowCallback, param);
  35. }
  36. else
  37. {
  38. if (numOfRows == 0)
  39. {
  40. Console.WriteLine("async retrieve complete.");
  41. }
  42. else
  43. {
  44. Console.WriteLine($"FetchRowAsync callback error, error code {numOfRows}");
  45. }
  46. TDengine.FreeResult(taosRes);
  47. }
  48. }
  49. public static void DisplayRes(IntPtr res)
  50. {
  51. if (!IsValidResult(res))
  52. {
  53. TDengine.Cleanup();
  54. System.Environment.Exit(1);
  55. }
  56. List<TDengineMeta> metaList = TDengine.FetchFields(res);
  57. int fieldCount = metaList.Count;
  58. // metaList.ForEach((item) => { Console.Write("{0} ({1}) \t|\t", item.name, item.size); });
  59. List<object> dataList = QueryRes(res, metaList);
  60. for (int index = 0; index < dataList.Count; index++)
  61. {
  62. if (index % fieldCount == 0 && index != 0)
  63. {
  64. Console.WriteLine("");
  65. }
  66. Console.Write("{0} \t|\t", dataList[index].ToString());
  67. }
  68. Console.WriteLine("");
  69. }
  70. public static bool IsValidResult(IntPtr res)
  71. {
  72. if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
  73. {
  74. if (res != IntPtr.Zero)
  75. {
  76. Console.Write("reason: " + TDengine.Error(res));
  77. return false;
  78. }
  79. Console.WriteLine("");
  80. return false;
  81. }
  82. return true;
  83. }
  84. private static List<object> QueryRes(IntPtr res, List<TDengineMeta> meta)
  85. {
  86. IntPtr taosRow;
  87. List<object> dataRaw = new();
  88. while ((taosRow = TDengine.FetchRows(res)) != IntPtr.Zero)
  89. {
  90. dataRaw.AddRange(FetchRow(taosRow, res));
  91. }
  92. if (TDengine.ErrorNo(res) != 0)
  93. {
  94. Console.Write("Query is not complete, Error {0} {1}", TDengine.ErrorNo(res), TDengine.Error(res));
  95. }
  96. TDengine.FreeResult(res);
  97. Console.WriteLine("");
  98. return dataRaw;
  99. }
  100. public static List<object> FetchRow(IntPtr taosRow, IntPtr taosRes)//, List<TDengineMeta> metaList, int numOfFiled
  101. {
  102. List<TDengineMeta> metaList = TDengine.FetchFields(taosRes);
  103. int numOfFiled = TDengine.FieldCount(taosRes);
  104. List<object> dataRaw = new();
  105. IntPtr colLengthPrt = TDengine.FetchLengths(taosRes);
  106. int[] colLengthArr = new int[numOfFiled];
  107. Marshal.Copy(colLengthPrt, colLengthArr, 0, numOfFiled);
  108. for (int i = 0; i < numOfFiled; i++)
  109. {
  110. TDengineMeta meta = metaList[i];
  111. IntPtr data = Marshal.ReadIntPtr(taosRow, IntPtr.Size * i);
  112. if (data == IntPtr.Zero)
  113. {
  114. dataRaw.Add("NULL");
  115. continue;
  116. }
  117. switch ((TDengineDataType)meta.type)
  118. {
  119. case TDengineDataType.TSDB_DATA_TYPE_BOOL:
  120. bool v1 = Marshal.ReadByte(data) != 0;
  121. dataRaw.Add(v1);
  122. break;
  123. case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
  124. sbyte v2 = (sbyte)Marshal.ReadByte(data);
  125. dataRaw.Add(v2);
  126. break;
  127. case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
  128. short v3 = Marshal.ReadInt16(data);
  129. dataRaw.Add(v3);
  130. break;
  131. case TDengineDataType.TSDB_DATA_TYPE_INT:
  132. int v4 = Marshal.ReadInt32(data);
  133. dataRaw.Add(v4);
  134. break;
  135. case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
  136. long v5 = Marshal.ReadInt64(data);
  137. dataRaw.Add(v5);
  138. break;
  139. case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
  140. float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
  141. dataRaw.Add(v6);
  142. break;
  143. case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
  144. double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
  145. dataRaw.Add(v7);
  146. break;
  147. case TDengineDataType.TSDB_DATA_TYPE_BINARY:
  148. string v8 = Marshal.PtrToStringUTF8(data, colLengthArr[i]);
  149. dataRaw.Add(v8);
  150. break;
  151. case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
  152. long v9 = Marshal.ReadInt64(data);
  153. dataRaw.Add(v9);
  154. break;
  155. case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
  156. string v10 = Marshal.PtrToStringUTF8(data, colLengthArr[i]);
  157. dataRaw.Add(v10);
  158. break;
  159. case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
  160. byte v12 = Marshal.ReadByte(data);
  161. dataRaw.Add(v12.ToString());
  162. break;
  163. case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
  164. ushort v13 = (ushort)Marshal.ReadInt16(data);
  165. dataRaw.Add(v13);
  166. break;
  167. case TDengineDataType.TSDB_DATA_TYPE_UINT:
  168. uint v14 = (uint)Marshal.ReadInt32(data);
  169. dataRaw.Add(v14);
  170. break;
  171. case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
  172. ulong v15 = (ulong)Marshal.ReadInt64(data);
  173. dataRaw.Add(v15);
  174. break;
  175. case TDengineDataType.TSDB_DATA_TYPE_JSONTAG:
  176. string v16 = Marshal.PtrToStringUTF8(data, colLengthArr[i]);
  177. dataRaw.Add(v16);
  178. break;
  179. default:
  180. dataRaw.Add("nonsupport data type");
  181. break;
  182. }
  183. }
  184. return dataRaw;
  185. }
  186. static IntPtr GetConnection()
  187. {
  188. string host = "localhost";
  189. short port = 6030;
  190. string username = "root";
  191. string password = "taosdata";
  192. string dbname = "power";
  193. var conn = TDengine.Connect(host, username, password, dbname, port);
  194. if (conn == IntPtr.Zero)
  195. {
  196. Console.WriteLine("Connect to TDengine failed");
  197. Environment.Exit(0);
  198. }
  199. else
  200. {
  201. Console.WriteLine("Connect to TDengine success");
  202. }
  203. return conn;
  204. }
  205. }
  206. }
  207. //output:
  208. // Connect to TDengine success
  209. // 8 rows async retrieved
  210. // 1538548685500 | 11.8 | 221 | 0.28 | california.losangeles | 2 |
  211. // 1538548696600 | 13.4 | 223 | 0.29 | california.losangeles | 2 |
  212. // 1538548685000 | 10.8 | 223 | 0.29 | california.losangeles | 3 |
  213. // 1538548686500 | 11.5 | 221 | 0.35 | california.losangeles | 3 |
  214. // 1538548685000 | 10.3 | 219 | 0.31 | california.sanfrancisco | 2 |
  215. // 1538548695000 | 12.6 | 218 | 0.33 | california.sanfrancisco | 2 |
  216. // 1538548696800 | 12.3 | 221 | 0.31 | california.sanfrancisco | 2 |
  217. // 1538548696650 | 10.3 | 218 | 0.25 | california.sanfrancisco | 3 |
  218. // async retrieve complete.

view source code

More sample programs

Sample programSample program description
C#checkerUsing TDengine.Connector, you can test C# Driver’s synchronous writes and queries
TDengineTestA simple example of writing and querying using TDengine.
insertCnExample of writing and querying Chinese characters using TDengine.
jsonTagExample of writing and querying JSON tag type data using TDengine.
stmtExample of parameter binding using TDengine.
schemalessExample of writing with schemaless implemented using TDengine.
benchmarkA simple benchmark implemented using TDengine.
async queryExample of an asynchronous query implemented using TDengine. Example of an asynchronous query
subscribeExample of subscribing to data using TDengine. Data example

Important update records

TDengine.ConnectorDescription
1.0.6Fix schemaless bug in 1.0.4 and 1.0.5.
1.0.5Fix Windows sync query Chinese error bug.
1.0.4Add asynchronous query, subscription, and other functions. Fix the binding parameter bug.
1.0.3Add parameter binding, schemaless, JSON tag, etc.
1.0.2Add connection management, synchronous query, error messages, etc. ## Other

Other descriptions

Third-party driver

Taos is an ADO.NET connector for TDengine, supporting Linux and Windows platforms. Community contributor Maikebing@@maikebing contributes the connector. Please refer to:

Frequently Asked Questions

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

    Usually, it’s caused by an incorrect FQDN configuration. Please refer to this section in the FAQ to troubleshoot.

  2. Unhandled exception. System.DllNotFoundException: Unable to load DLL ‘taos’ or one of its dependencies: The specified module cannot be found.

    This is usually because the program did not find the dependent client driver. The solution is to copy C:\TDengine\driver\taos.dll to the C:\Windows\System32\ directory on Windows, and create the following soft link on Linux ln -s /usr/local/taos/driver/libtaos.so.x.x .x.x /usr/lib/libtaos.so will work.

API Reference

API Reference