diff --git a/CMakeLists.txt b/CMakeLists.txt
index 66a6fd328d..ac368c29fe 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,6 +41,7 @@ add_subdirectory(source)
add_subdirectory(tools)
add_subdirectory(utils)
add_subdirectory(examples/c)
+add_subdirectory(tests)
include(${TD_SUPPORT_DIR}/cmake.install)
# docs
diff --git a/deps/arm/dm_static/libdmodule.a b/deps/arm/dm_static/libdmodule.a
index fff5943606..9e69059651 100644
Binary files a/deps/arm/dm_static/libdmodule.a and b/deps/arm/dm_static/libdmodule.a differ
diff --git a/deps/darwin/arm/dm_static/libdmodule.a b/deps/darwin/arm/dm_static/libdmodule.a
index 09c501f2ef..5fbfc4dd58 100644
Binary files a/deps/darwin/arm/dm_static/libdmodule.a and b/deps/darwin/arm/dm_static/libdmodule.a differ
diff --git a/deps/darwin/x64/dm_static/libdmodule.a b/deps/darwin/x64/dm_static/libdmodule.a
index 2230393565..9f81fe8381 100644
Binary files a/deps/darwin/x64/dm_static/libdmodule.a and b/deps/darwin/x64/dm_static/libdmodule.a differ
diff --git a/deps/x86/dm_static/libdmodule.a b/deps/x86/dm_static/libdmodule.a
index 995713ce7b..cce0217501 100644
Binary files a/deps/x86/dm_static/libdmodule.a and b/deps/x86/dm_static/libdmodule.a differ
diff --git a/docs/en/07-develop/01-connect/index.md b/docs/en/07-develop/01-connect/index.md
index 3f09f9fb6a..11375bd060 100644
--- a/docs/en/07-develop/01-connect/index.md
+++ b/docs/en/07-develop/01-connect/index.md
@@ -177,7 +177,7 @@ Just need to add the reference to [TDengine.Connector](https://www.nuget.org/pac
-
+
diff --git a/docs/en/07-develop/04-query-data/_cs_async.mdx b/docs/en/07-develop/04-query-data/_cs_async.mdx
deleted file mode 100644
index 19c8e58f32..0000000000
--- a/docs/en/07-develop/04-query-data/_cs_async.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-```csharp
-{{#include docs/examples/csharp/asyncQuery/Program.cs}}
-```
diff --git a/docs/en/07-develop/04-query-data/index.mdx b/docs/en/07-develop/04-query-data/index.mdx
index 413baf6b2c..70b1140748 100644
--- a/docs/en/07-develop/04-query-data/index.mdx
+++ b/docs/en/07-develop/04-query-data/index.mdx
@@ -15,7 +15,6 @@ import CQuery from "./_c.mdx";
import PhpQuery from "./_php.mdx";
import PyAsync from "./_py_async.mdx";
import NodeAsync from "./_js_async.mdx";
-import CsAsync from "./_cs_async.mdx";
import CAsync from "./_c_async.mdx";
## Introduction
@@ -174,9 +173,6 @@ Please note that async query can only be used with a native connection.
-
-
-
diff --git a/docs/en/07-develop/07-tmq.mdx b/docs/en/07-develop/07-tmq.mdx
index 8e7bbf22e9..b920d61a59 100644
--- a/docs/en/07-develop/07-tmq.mdx
+++ b/docs/en/07-develop/07-tmq.mdx
@@ -248,23 +248,23 @@ function close()
```csharp
+class ConsumerBuilder
+
ConsumerBuilder(IEnumerable> config)
-virtual IConsumer Build()
-
-Consumer(ConsumerBuilder builder)
+public IConsumer Build()
void Subscribe(IEnumerable topics)
void Subscribe(string topic)
-ConsumeResult Consume(int millisecondsTimeout)
+ConsumeResult Consume(int millisecondsTimeout)
List Subscription()
void Unsubscribe()
-void Commit(ConsumeResult consumerResult)
+List Commit()
void Close()
```
@@ -500,25 +500,19 @@ let consumer = taos.consumer({
```csharp
-using TDengineTMQ;
-
-// Create consumer groups on demand (GourpID) and enable automatic commits (EnableAutoCommit),
-// an automatic commit interval (AutoCommitIntervalMs), and a username (TDConnectUser) and password (TDConnectPasswd)
-var cfg = new ConsumerConfig
- {
- EnableAutoCommit = "true"
- AutoCommitIntervalMs = "1000"
- GourpId = "TDengine-TMQ-C#",
- TDConnectUser = "root",
- TDConnectPasswd = "taosdata",
- AutoOffsetReset = "latest"
- MsgWithTableName = "true",
- TDConnectIp = "127.0.0.1",
- TDConnectPort = "6030"
- };
-
-var consumer = new ConsumerBuilder(cfg).Build();
-
+var cfg = new Dictionary()
+{
+ { "group.id", "group1" },
+ { "auto.offset.reset", "latest" },
+ { "td.connect.ip", "127.0.0.1" },
+ { "td.connect.user", "root" },
+ { "td.connect.pass", "taosdata" },
+ { "td.connect.port", "6030" },
+ { "client.id", "tmq_example" },
+ { "enable.auto.commit", "true" },
+ { "msg.with.table.name", "false" },
+};
+var consumer = new ConsumerBuilder>(cfg).Build();
```
@@ -747,10 +741,12 @@ while(true){
## Consume data
while (true)
{
- var consumerRes = consumer.Consume(100);
- // process ConsumeResult
- ProcessMsg(consumerRes);
- consumer.Commit(consumerRes);
+ using (var result = consumer.Consume(500))
+ {
+ if (result == null) continue;
+ ProcessMsg(result);
+ consumer.Commit();
+ }
}
```
diff --git a/docs/en/14-reference/02-rest-api/02-rest-api.mdx b/docs/en/14-reference/02-rest-api/02-rest-api.mdx
index 8f8e966f8d..5cb680e34b 100644
--- a/docs/en/14-reference/02-rest-api/02-rest-api.mdx
+++ b/docs/en/14-reference/02-rest-api/02-rest-api.mdx
@@ -262,6 +262,63 @@ The following types may be returned:
- "INT UNSIGNED"
- "BIGINT UNSIGNED"
- "JSON"
+- "VARBINARY"
+- "GEOMETRY"
+
+`VARBINARY` and `GEOMETRY` types return data as Hex string, example:
+
+Prepare data
+
+```bash
+create database demo
+use demo
+create table t(ts timestamp,c1 varbinary(20),c2 geometry(100))
+insert into t values(now,'\x7f8290','point(100 100)')
+```
+
+Execute query
+
+```bash
+curl --location 'http://:/rest/sql' \
+--header 'Content-Type: text/plain' \
+--header 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' \
+--data 'select * from demo.t'
+```
+
+Return results
+
+```json
+{
+ "code": 0,
+ "column_meta": [
+ [
+ "ts",
+ "TIMESTAMP",
+ 8
+ ],
+ [
+ "c1",
+ "VARBINARY",
+ 20
+ ],
+ [
+ "c2",
+ "GEOMETRY",
+ 100
+ ]
+ ],
+ "data": [
+ [
+ "2023-11-01T06:28:15.210Z",
+ "7f8290",
+ "010100000000000000000059400000000000005940"
+ ]
+ ],
+ "rows": 1
+}
+```
+
+- `010100000000000000000059400000000000005940` is [Well-Known Binary (WKB)](https://libgeos.org/specifications/wkb/) format for `point(100 100)`
#### Errors
diff --git a/docs/en/14-reference/03-connector/09-csharp.mdx b/docs/en/14-reference/03-connector/09-csharp.mdx
index 282be3af6b..25bef1cf51 100644
--- a/docs/en/14-reference/03-connector/09-csharp.mdx
+++ b/docs/en/14-reference/03-connector/09-csharp.mdx
@@ -1,5 +1,5 @@
---
-title: C# Connector
+title: TDengine C# Connector
sidebar_label: C#
description: This document describes the TDengine C# connector.
toc_max_heading_level: 4
@@ -8,21 +8,16 @@ toc_max_heading_level: 4
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
-import Preparition from "./_preparation.mdx"
-import CSInsert from "../../07-develop/03-insert-data/_cs_sql.mdx"
-import CSInfluxLine from "../../07-develop/03-insert-data/_cs_line.mdx"
-import CSOpenTSDBTelnet from "../../07-develop/03-insert-data/_cs_opts_telnet.mdx"
-import CSOpenTSDBJson from "../../07-develop/03-insert-data/_cs_opts_json.mdx"
-import CSQuery from "../../07-develop/04-query-data/_cs.mdx"
-import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx"
+`TDengine.Connector` is the C# language connector provided by TDengine. C# developers can use it to develop C# application software that accesses TDengine cluster data.
-`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 establishing a connection with the TDengine running instance through the TDengine client driver (taosc), and provides functions such as data writing, query, data subscription, schemaless data writing, and parameter binding interface data writing. `TDengine.Connector` also supports WebSocket since v3.0.1, establishes WebSocket connection, and provides functions such as data writing, query, and parameter binding interface data writing.
-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` also supports WebSocket from v3.0.1 and developers can build connection through DSN, which supports data writing, querying, and parameter binding, etc.
+This article introduces how to install `TDengine.Connector` in a Linux or Windows environment, and connect to the TDengine cluster through `TDengine.Connector` to perform basic operations such as data writing and querying.
-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.
-
-Note: TDengine Connector 3.x is not compatible with TDengine 2.x. In an environment with TDengine 2.x, you must use TDengine.Connector 1.x for the C# connector.
+:::warning
+* `TDengine.Connector` version 3.1.0 has been completely refactored and is no longer compatible with 3.0.2 and previous versions. For 3.0.2 documents, please refer to [nuget](https://www.nuget.org/packages/TDengine.Connector/3.0.2)
+* `TDengine.Connector` 3.x is not compatible with TDengine 2.x. If you need to use the C# connector in an environment running TDengine 2.x version, please use the 1.x version of TDengine.Connector.
+:::
The source code of `TDengine.Connector` is hosted on [GitHub](https://github.com/taosdata/taos-connector-dotnet/tree/3.0).
@@ -30,286 +25,1164 @@ The source code of `TDengine.Connector` is hosted on [GitHub](https://github.com
The supported platforms are the same as those supported by the TDengine client driver.
-:::note
-Please note TDengine does not support 32bit Windows any more.
+:::warning
+TDengine no longer supports 32-bit Windows platforms.
:::
## Version support
-Please refer to [version support list](../#version-support)
+| **Connector version** | **TDengine version** |
+|-----------------------|----------------------|
+| 3.1.0 | 3.2.1.0/3.1.1.18 |
-## Supported features
+## Handling exceptions
-
+`TDengine.Connector` will throw an exception and the application needs to handle the exception. The taosc exception type `TDengineError` contains error code and error information, and the application can handle it based on the error code and error information.
-
+## TDengine DataType vs. C# DataType
-1. Connection Management
-2. General Query
-3. Continuous Query
-4. Parameter Binding
-5. Subscription
-6. Schemaless
+| TDengine DataType | C# Type |
+|-------------------|-------------------------|
+| TIMESTAMP | DateTime |
+| TINYINT | sbyte |
+| SMALLINT | short |
+| INT | int |
+| BIGINT | long |
+| TINYINT UNSIGNED | byte |
+| SMALLINT UNSIGNED | ushort |
+| INT UNSIGNED | uint |
+| BIGINT UNSIGNED | ulong |
+| FLOAT | float |
+| DOUBLE | double |
+| BOOL | bool |
+| BINARY | byte[] |
+| NCHAR | string (utf-8 encoding) |
+| JSON | byte[] |
-
-
-
-
-1. Connection Management
-2. General Query
-3. Continuous Query
-4. Parameter Binding
-
-
-
+**Note**: JSON type is only supported in tag.
## Installation Steps
### Pre-installation preparation
-* Install the [.NET SDK](https://dotnet.microsoft.com/download)
+* Install [.NET SDK](https://dotnet.microsoft.com/download)
* [Nuget Client](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (optional installation)
-* Install TDengine client driver, please refer to [Install client driver](../#install-client-driver) for details
+* Install the TDengine client driver. For specific steps, please refer to [Installing the client driver](../#install-client-driver)
-### Install `TDengine.Connector`
+### Install the connectors
-
-
+Nuget package `TDengine.Connector` can be added to the current project through dotnet CLI under the path of the current .NET project.
-You can reference the `TDengine.Connector` published in Nuget to the current project via the `dotnet` CLI under the path of the existing .NET project.
-
-``` bash
+```bash
dotnet add package TDengine.Connector
```
-You may also modify the current.NET project file. You can include the following 'ItemGroup' in your project file (.csproj).
+You can also modify the `.csproj` file of the current project and add the following ItemGroup.
``` XML
-
-
-
+
+
+
```
-
-
+## Establishing a connection
-In this scenario, modifying your project file is required in order to copy the WebSocket dependency dynamic library from the nuget package into your project.
-```XML
-
-
-
-
-
-
-
-
-
-```
-
-Notice: `TDengine.Connector` only version>= 3.0.2 includes the dynamic library for WebSocket.
-
-
-
-
-## Establish a Connection
-
-
-
-
-
+
+
``` csharp
-using TDengineDriver;
-
-namespace TDengineExample
+var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+using (var client = DbDriver.Open(builder))
{
-
- internal class EstablishConnection
- {
- static void Main(String[] args)
- {
- string host = "localhost";
- short port = 6030;
- string username = "root";
- string password = "taosdata";
- string dbname = "";
-
- var conn = TDengine.Connect(host, username, password, dbname, port);
- if (conn == IntPtr.Zero)
- {
- Console.WriteLine("Connect to TDengine failed");
- }
- else
- {
- Console.WriteLine("Connect to TDengine success");
- }
- TDengine.Close(conn);
- TDengine.Cleanup();
- }
- }
+ Console.WriteLine("connected")
}
-
```
+
-
-
-The structure of the DSN description string is as follows:
-
-```text
-[]://[[:@]:][/][?=[&=]]
-|------------|---|-----------|-----------|------|------|------------|-----------------------|
-| protocol | | username | password | host | port | database | params |
-```
-
-The parameters are described as follows:
-
-* **protocol**: Specify which connection method to use (support http/ws). For example, `ws://localhost:6041` uses Websocket to establish connections.
-* **username/password**: Username and password used to create connections.
-* **host/port**: Specifies the server and port to establish a connection. Websocket connections default to `localhost:6041`.
-* **database**: Specify the default database to connect to. It's optional.
-* **params**: Optional parameters.
-
-A sample DSN description string is as follows:
-
-```text
-ws://localhost:6041/test
-```
-
-``` csharp
-{{#include docs/examples/csharp/wsConnect/Program.cs}}
+```csharp
+var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+using (var client = DbDriver.Open(builder))
+{
+ Console.WriteLine("connected")
+}
```
+The parameters supported by `ConnectionStringBuilder` are as follows:
+* protocol: connection protocol, optional value is Native or WebSocket, default is Native
+* host: the address of the running instance of TDengine or taosadapter,
+* port: The port of the running instance of TDengine or taosadapter.
+ * When using WebSocket without SSL, the default is 6041.
+ * When using WebSocket with SSL, the default is 443.
+* useSSL: Whether to use SSL, the default is false, only valid when the protocol is WebSocket
+* token: The token used to connect to TDengine Cloud, only valid when the protocol is WebSocket
+* username: username to connect to TDengine
+* password: password to connect to TDengine
+* db: database connected to TDengine
+* timezone: The time zone for parsing time results, the default is `TimeZoneInfo.Local`, use the `TimeZoneInfo.FindSystemTimeZoneById` method to parse the string into a `TimeZoneInfo` object.
+* connTimeout: WebSocket connection timeout, only valid when the protocol is WebSocket, the default is 1 minute, use the `TimeSpan.Parse` method to parse the string into a `TimeSpan` object.
+* readTimeout: WebSocket read timeout, only valid when the protocol is WebSocket, the default is 5 minutes, use the `TimeSpan.Parse` method to parse the string into a `TimeSpan` object.
+* writeTimeout: WebSocket write timeout, only valid when the protocol is WebSocket, the default is 10 seconds, use the `TimeSpan.Parse` method to parse the string into a `TimeSpan` object.
+
+### Specify the URL and Properties to get the connection
+
+The C# connector does not support this feature
+
+### Priority of configuration parameters
+
+The C# connector does not support this feature
+
## Usage examples
-### Write data
+### Create database and tables
-#### SQL Write
-
-
-
-
-
-
-
-
-
-
+
+
```csharp
-{{#include docs/examples/csharp/wsInsert/Program.cs}}
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace NativeQuery
+{
+ internal class Query
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("create database power");
+ client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+```csharp
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace WSQuery
+{
+ internal class Query
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("create database power");
+ client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
```
-#### InfluxDB line protocol write
+### Insert data
-
+
+
-#### OpenTSDB Telnet line protocol write
+```csharp
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
-
-
-#### OpenTSDB JSON line protocol write
-
-
-
-#### Parameter Binding
-
-
-
-
-
-``` csharp
-{{#include docs/examples/csharp/stmtInsert/Program.cs}}
+namespace NativeQuery
+{
+ internal class Query
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ string insertQuery =
+ "INSERT INTO " +
+ "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
+ "VALUES " +
+ "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " +
+ "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " +
+ "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " +
+ "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " +
+ "VALUES " +
+ "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " +
+ "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " +
+ "VALUES " +
+ "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " +
+ "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " +
+ "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " +
+ "VALUES " +
+ "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " +
+ "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)";
+ client.Exec(insertQuery);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
```
-
-
+
```csharp
-{{#include docs/examples/csharp/wsStmt/Program.cs}}
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace WSQuery
+{
+ internal class Query
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ string insertQuery =
+ "INSERT INTO " +
+ "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
+ "VALUES " +
+ "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " +
+ "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " +
+ "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " +
+ "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " +
+ "VALUES " +
+ "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " +
+ "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " +
+ "VALUES " +
+ "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " +
+ "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " +
+ "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " +
+ "VALUES " +
+ "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " +
+ "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)";
+ client.Exec(insertQuery);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
```
-### Query data
+### Querying data
-#### Synchronous Query
-
-
-
-
-
-
-
-
-
-
+
+
```csharp
-{{#include docs/examples/csharp/wsQuery/Program.cs}}
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace NativeQuery
+{
+ internal class Query
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("use power");
+ string query = "SELECT * FROM meters";
+ using (var rows = client.Query(query))
+ {
+ while (rows.Read())
+ {
+ Console.WriteLine($"{((DateTime)rows.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {rows.GetValue(1)}, {rows.GetValue(2)}, {rows.GetValue(3)}, {rows.GetValue(4)}, {Encoding.UTF8.GetString((byte[])rows.GetValue(5))}");
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+```csharp
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace WSQuery
+{
+ internal class Query
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("use power");
+ string query = "SELECT * FROM meters";
+ using (var rows = client.Query(query))
+ {
+ while (rows.Read())
+ {
+ Console.WriteLine($"{((DateTime)rows.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {rows.GetValue(1)}, {rows.GetValue(2)}, {rows.GetValue(3)}, {rows.GetValue(4)}, {Encoding.UTF8.GetString((byte[])rows.GetValue(5))}");
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
```
-#### Asynchronous query
+### execute SQL with reqId
-
+
+
+
+```csharp
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace NativeQueryWithReqID
+{
+ internal abstract class QueryWithReqID
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec($"create database if not exists test_db",ReqId.GetReqId());
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+```csharp
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace WSQueryWithReqID
+{
+ internal abstract class QueryWithReqID
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec($"create database if not exists test_db",ReqId.GetReqId());
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+### Writing data via parameter binding
+
+
+
+
+```csharp
+using System;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace NativeStmt
+{
+ internal abstract class NativeStmt
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("create database power");
+ client.Exec(
+ "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ using (var stmt = client.StmtInit())
+ {
+ stmt.Prepare(
+ "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)");
+ var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000);
+ stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 });
+ stmt.AddBatch();
+ stmt.Exec();
+ var affected = stmt.Affected();
+ Console.WriteLine($"affected rows: {affected}");
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+```csharp
+using System;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace WSStmt
+{
+ internal abstract class WSStmt
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("create database power");
+ client.Exec(
+ "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ using (var stmt = client.StmtInit())
+ {
+ stmt.Prepare(
+ "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)");
+ var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000);
+ stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 });
+ stmt.AddBatch();
+ stmt.Exec();
+ var affected = stmt.Affected();
+ Console.WriteLine($"affected rows: {affected}");
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+Note: When using BindRow, you need to pay attention to the one-to-one correspondence between the original C# column type and the TDengine column type. For the specific correspondence, please refer to [TDengine DataType and C# DataType](#tdengine-datatype-vs-c-datatype).
+
+### Schemaless Writing
+
+
+
+
+```csharp
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace NativeSchemaless
+{
+ internal class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder =
+ new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ client.Exec("create database sml");
+ client.Exec("use sml");
+ var influxDBData =
+ "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000";
+ client.SchemalessInsert(new string[] { influxDBData },
+ TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL,
+ TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NANO_SECONDS, 0, ReqId.GetReqId());
+ var telnetData = "stb0_0 1626006833 4 host=host0 interface=eth0";
+ client.SchemalessInsert(new string[] { telnetData },
+ TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL,
+ TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
+ var jsonData =
+ "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}";
+ client.SchemalessInsert(new string[] { jsonData }, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL,
+ TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
+ }
+ }
+ }
+}
+```
+
+
+
+
+```csharp
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace WSSchemaless
+{
+ internal class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder =
+ new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ client.Exec("create database sml");
+ client.Exec("use sml");
+ var influxDBData =
+ "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000";
+ client.SchemalessInsert(new string[] { influxDBData },
+ TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL,
+ TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NANO_SECONDS, 0, ReqId.GetReqId());
+ var telnetData = "stb0_0 1626006833 4 host=host0 interface=eth0";
+ client.SchemalessInsert(new string[] { telnetData },
+ TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL,
+ TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
+ var jsonData =
+ "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}";
+ client.SchemalessInsert(new string[] { jsonData }, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL,
+ TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
+ }
+ }
+ }
+}
+```
+
+
+
+
+### Schemaless with reqId
+
+```csharp
+public void SchemalessInsert(string[] lines, TDengineSchemalessProtocol protocol,
+ TDengineSchemalessPrecision precision,
+ int ttl, long reqId)
+```
+
+### Data Subscription
+
+#### Create a Topic
+
+
+
+
+```csharp
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace NativeSubscription
+{
+ internal class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("create database power");
+ client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+```csharp
+using System;
+using System.Text;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+
+namespace WSSubscription
+{
+ internal class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("create database power");
+ client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+#### Create a Consumer
+
+
+
+
+```csharp
+var cfg = new Dictionary()
+{
+ { "group.id", "group1" },
+ { "auto.offset.reset", "latest" },
+ { "td.connect.ip", "127.0.0.1" },
+ { "td.connect.user", "root" },
+ { "td.connect.pass", "taosdata" },
+ { "td.connect.port", "6030" },
+ { "client.id", "tmq_example" },
+ { "enable.auto.commit", "true" },
+ { "msg.with.table.name", "false" },
+};
+var consumer = new ConsumerBuilder>(cfg).Build();
+```
+
+
+
+
+```csharp
+var cfg = new Dictionary()
+{
+ { "td.connect.type", "WebSocket" },
+ { "group.id", "group1" },
+ { "auto.offset.reset", "latest" },
+ { "td.connect.ip", "localhost" },
+ { "td.connect.port","6041"},
+ { "useSSL", "false" },
+ { "td.connect.user", "root" },
+ { "td.connect.pass", "taosdata" },
+ { "client.id", "tmq_example" },
+ { "enable.auto.commit", "true" },
+ { "msg.with.table.name", "false" },
+};
+var consumer = new ConsumerBuilder>(cfg).Build();
+```
+
+
+
+
+The configuration parameters supported by consumer are as follows:
+* td.connect.type: connection type, optional value is Native or WebSocket, default is Native
+* td.connect.ip: The address of the TDengine running instance or taosadapter
+* td.connect.port: The port of the running instance of TDengine or taosadapter.
+ * When using WebSocket without SSL, the default is 6041.
+ * When using WebSocket with SSL, the default is 443.
+* useSSL: Whether to use SSL, the default is false, only valid when the protocol is WebSocket
+* token: The token used to connect to TDengine Cloud, only valid when the protocol is WebSocket
+* td.connect.user: username to connect to TDengine
+* td.connect.pass: Password for connecting to TDengine
+* group.id: consumer group ID
+* client.id: consumer ID
+* enable.auto.commit: Whether to automatically commit offset, the default is true
+* auto.commit.interval.ms: The interval for automatically submitting offsets, the default is 5000 milliseconds
+* auto.offset.reset: When offset does not exist, where to start consumption, the optional value is earliest or latest, the default is latest
+* msg.with.table.name: Whether the message contains the table name
+
+Supports subscribing to the result set `Dictionary` where the key is the column name and the value is the column value.
+
+If you use object to receive column values, you need to pay attention to:
+* There needs to be a one-to-one correspondence between the original C# column type and the TDengine column type. For specific correspondence, please refer to [TDengine DataType and C# DataType] (#tdengine-datatype-and-c-datatype).
+* The column name is consistent with the class attribute name and can be get and set.
+* Explicitly set the value parser `ConsumerBuilder.SetValueDeserializer(new ReferenceDeserializer());`
+
+An example is as follows
+
+Result class
+
+```csharp
+ class Result
+ {
+ public DateTime ts { get; set; }
+ public float current { get; set; }
+ public int voltage { get; set; }
+ public float phase { get; set; }
+ }
+```
+
+Set up parser
+
+```csharp
+var tmqBuilder = new ConsumerBuilder(cfg);
+tmqBuilder.SetValueDeserializer(new ReferenceDeserializer());
+var consumer = tmqBuilder.Build();
+```
+
+You can also implement a custom deserializer, implement the `IDeserializer` interface and pass it in through the `ConsumerBuilder.SetValueDeserializer` method.
+
+```csharp
+ public interface IDeserializer
+ {
+ T Deserialize(ITMQRows data, bool isNull, SerializationContext context);
+ }
+```
+
+#### Subscribe to consume data
+
+```csharp
+consumer.Subscribe(new List() { "topic_meters" });
+while (true)
+{
+ using (var cr = consumer.Consume(500))
+ {
+ if (cr == null) continue;
+ foreach (var message in cr.Message)
+ {
+ Console.WriteLine(
+ $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " +
+ $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}");
+ }
+ }
+}
+```
+
+#### Assignment subscription Offset
+
+```csharp
+consumer.Assignment.ForEach(a =>
+{
+ Console.WriteLine($"{a}, seek to 0");
+ consumer.Seek(new TopicPartitionOffset(a.Topic, a.Partition, 0));
+ Thread.Sleep(TimeSpan.FromSeconds(1));
+});
+```
+
+#### Commit offset
+
+```csharp
+public void Commit(ConsumeResult consumerResult)
+public List Commit()
+public void Commit(IEnumerable offsets)
+```
+
+#### Close subscriptions
+
+```csharp
+consumer.Unsubscribe();
+consumer.Close();
+```
+
+#### Full Sample Code
+
+
+
+
+```csharp
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+using TDengine.TMQ;
+
+namespace NativeSubscription
+{
+ internal class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("CREATE DATABASE power");
+ client.Exec("USE power");
+ client.Exec(
+ "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters");
+ var cfg = new Dictionary()
+ {
+ { "group.id", "group1" },
+ { "auto.offset.reset", "latest" },
+ { "td.connect.ip", "127.0.0.1" },
+ { "td.connect.user", "root" },
+ { "td.connect.pass", "taosdata" },
+ { "td.connect.port", "6030" },
+ { "client.id", "tmq_example" },
+ { "enable.auto.commit", "true" },
+ { "msg.with.table.name", "false" },
+ };
+ var consumer = new ConsumerBuilder>(cfg).Build();
+ consumer.Subscribe(new List() { "topic_meters" });
+ Task.Run(InsertData);
+ while (true)
+ {
+ using (var cr = consumer.Consume(500))
+ {
+ if (cr == null) continue;
+ foreach (var message in cr.Message)
+ {
+ Console.WriteLine(
+ $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " +
+ $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}");
+ }
+ consumer.Commit();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+
+ static void InsertData()
+ {
+ var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ while (true)
+ {
+ client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)");
+ Task.Delay(1000).Wait();
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+```csharp
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using TDengine.Driver;
+using TDengine.Driver.Client;
+using TDengine.TMQ;
+
+namespace WSSubscription
+{
+ internal class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ try
+ {
+ client.Exec("CREATE DATABASE power");
+ client.Exec("USE power");
+ client.Exec(
+ "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters");
+ var cfg = new Dictionary()
+ {
+ { "td.connect.type", "WebSocket" },
+ { "group.id", "group1" },
+ { "auto.offset.reset", "latest" },
+ { "td.connect.ip", "localhost" },
+ { "td.connect.port","6041"},
+ { "useSSL", "false" },
+ { "td.connect.user", "root" },
+ { "td.connect.pass", "taosdata" },
+ { "client.id", "tmq_example" },
+ { "enable.auto.commit", "true" },
+ { "msg.with.table.name", "false" },
+ };
+ var consumer = new ConsumerBuilder>(cfg).Build();
+ consumer.Subscribe(new List() { "topic_meters" });
+ Task.Run(InsertData);
+ while (true)
+ {
+ using (var cr = consumer.Consume(500))
+ {
+ if (cr == null) continue;
+ foreach (var message in cr.Message)
+ {
+ Console.WriteLine(
+ $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " +
+ $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}");
+ }
+ consumer.Commit();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ throw;
+ }
+ }
+ }
+
+ static void InsertData()
+ {
+ var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
+ using (var client = DbDriver.Open(builder))
+ {
+ while (true)
+ {
+ client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)");
+ Task.Delay(1000).Wait();
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+### ADO.NET
+
+The C# connector supports the ADO.NET interface, and you can connect to the TDengine running instance through the ADO.NET interface to perform operations such as data writing and querying.
+
+
+
+
+```csharp
+using System;
+using TDengine.Data.Client;
+
+namespace NativeADO
+{
+ internal class Program
+ {
+ public static void Main(string[] args)
+ {
+ const string connectionString = "host=localhost;port=6030;username=root;password=taosdata";
+ using (var connection = new TDengineConnection(connectionString))
+ {
+ try
+ {
+ connection.Open();
+ using (var command = new TDengineCommand(connection))
+ {
+ command.CommandText = "create database power";
+ command.ExecuteNonQuery();
+ connection.ChangeDatabase("power");
+ command.CommandText =
+ "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))";
+ command.ExecuteNonQuery();
+ command.CommandText = "INSERT INTO " +
+ "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
+ "VALUES " +
+ "(?,?,?,?)";
+ var parameters = command.Parameters;
+ parameters.Add(new TDengineParameter("@0", new DateTime(2023,10,03,14,38,05,000)));
+ parameters.Add(new TDengineParameter("@1", (float)10.30000));
+ parameters.Add(new TDengineParameter("@2", (int)219));
+ parameters.Add(new TDengineParameter("@3", (float)0.31000));
+ command.ExecuteNonQuery();
+ command.Parameters.Clear();
+ command.CommandText = "SELECT * FROM meters";
+ using (var reader = command.ExecuteReader())
+ {
+ while (reader.Read())
+ {
+ Console.WriteLine(
+ $"{((DateTime) reader.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {reader.GetValue(1)}, {reader.GetValue(2)}, {reader.GetValue(3)}, {reader.GetValue(4)}, {System.Text.Encoding.UTF8.GetString((byte[]) reader.GetValue(5))}");
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+```csharp
+using System;
+using TDengine.Data.Client;
+
+namespace WSADO
+{
+ internal class Program
+ {
+ public static void Main(string[] args)
+ {
+ const string connectionString = "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata";
+ using (var connection = new TDengineConnection(connectionString))
+ {
+ try
+ {
+ connection.Open();
+ using (var command = new TDengineCommand(connection))
+ {
+ command.CommandText = "create database power";
+ command.ExecuteNonQuery();
+ connection.ChangeDatabase("power");
+ command.CommandText =
+ "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))";
+ command.ExecuteNonQuery();
+ command.CommandText = "INSERT INTO " +
+ "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
+ "VALUES " +
+ "(?,?,?,?)";
+ var parameters = command.Parameters;
+ parameters.Add(new TDengineParameter("@0", new DateTime(2023,10,03,14,38,05,000)));
+ parameters.Add(new TDengineParameter("@1", (float)10.30000));
+ parameters.Add(new TDengineParameter("@2", (int)219));
+ parameters.Add(new TDengineParameter("@3", (float)0.31000));
+ command.ExecuteNonQuery();
+ command.Parameters.Clear();
+ command.CommandText = "SELECT * FROM meters";
+ using (var reader = command.ExecuteReader())
+ {
+ while (reader.Read())
+ {
+ Console.WriteLine(
+ $"{((DateTime) reader.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {reader.GetValue(1)}, {reader.GetValue(2)}, {reader.GetValue(3)}, {reader.GetValue(4)}, {System.Text.Encoding.UTF8.GetString((byte[]) reader.GetValue(5))}");
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+ }
+ }
+}
+```
+
+
+
+
+* The connection parameters are consistent with those in [Establishing a connection](#establishing-a-connection).
+* The name of TDengineParameter needs to start with @, such as @0, @1, @2, etc. The value needs to have a one-to-one correspondence between the C# column type and the TDengine column type. For the specific correspondence, please refer to [TDengine DataType and C# DataType](#tdengine-datatype-vs-c-datatype).
### More sample programs
-|Sample program |Sample program description |
-|--------------------------------------------------------------------------------------------------------------------|--------------------------------------------|
-| [CURD](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/Query/Query.cs) | Table creation, data insertion, and query examples with TDengine.Connector |
-| [JSON Tag](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/JSONTag) | Writing and querying JSON tag data with TDengine Connector |
-| [stmt](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples/NET6Examples/Stmt) | Parameter binding with TDengine Connector |
-| [schemaless](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/schemaless) | Schemaless writes with TDengine Connector |
-| [async query](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/AsyncQuery/QueryAsync.cs) | Asynchronous queries with TDengine Connector |
-| [Subscription](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/TMQ/TMQ.cs) | Subscription example with TDengine Connector |
-| [Basic WebSocket Usage](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/FrameWork45/WS/WebSocketSample.cs) | WebSocket basic data in and out with TDengine connector |
-| [WebSocket Parameter Binding](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/FrameWork45/WS/WebSocketSTMT.cs) | WebSocket parameter binding example |
-
-## Important update records
-
-| TDengine.Connector | Description |
-|--------------------|--------------------------------|
-| 3.0.2 | Support .NET Framework 4.5 and above. Support .Net standard 2.0. Nuget package includes dynamic library for WebSocket.|
-| 3.0.1 | Support WebSocket and Cloud, With function query, insert, and parameter binding|
-| 3.0.0 | Supports TDengine 3.0.0.0. TDengine 2.x is not supported. Added `TDengine.Impl.GetData()` interface to deserialize query results. |
-| 1.0.7 | Fixed TDengine.Query() memory leak. |
-| 1.0.6 | Fix schemaless bug in 1.0.4 and 1.0.5. |
-| 1.0.5 | Fix Windows sync query Chinese error bug. | 1.0.4 | Fix schemaless bug. |
-| 1.0.4 | Add asynchronous query, subscription, and other functions. Fix the binding parameter bug. |
-| 1.0.3 | Add parameter binding, schemaless, JSON tag, etc. |
-| 1.0.2 | Add connection management, synchronous query, error messages, etc. |
-
-## 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:
-
-* Interface download:
-
-## 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](https://docs.tdengine.com/2.4/train-faq/faq/#2-how-to-handle-unable-to-establish-connection) 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](https://docs.taosdata.com/api/connector-csharp/html/860d2ac1-dd52-39c9-e460-0829c4e5a40b.htm)
+[sample program](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples)
\ No newline at end of file
diff --git a/docs/examples/csharp/.gitignore b/docs/examples/csharp/.gitignore
index c228f1be2a..b0df020f44 100644
--- a/docs/examples/csharp/.gitignore
+++ b/docs/examples/csharp/.gitignore
@@ -1,5 +1,5 @@
.vs
-asyncQuery/bin
+.idea
connect/bin
influxdbLine/bin
optsJSON/bin
@@ -12,7 +12,6 @@ wsConnect/bin
wsInsert/bin
wsQuery/bin
wsStmt/bin
-asyncQuery/obj
connect/obj
influxdbLine/obj
optsJSON/obj
diff --git a/docs/examples/csharp/asyncQuery/Program.cs b/docs/examples/csharp/asyncQuery/Program.cs
deleted file mode 100644
index 864f06a15e..0000000000
--- a/docs/examples/csharp/asyncQuery/Program.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using System;
-using System.Collections.Generic;
-using TDengineDriver;
-using TDengineDriver.Impl;
-using System.Runtime.InteropServices;
-
-namespace TDengineExample
-{
- public class AsyncQueryExample
- {
- static void Main()
- {
- IntPtr conn = GetConnection();
- try
- {
- QueryAsyncCallback queryAsyncCallback = new QueryAsyncCallback(QueryCallback);
- TDengine.QueryAsync(conn, "select * from meters", queryAsyncCallback, IntPtr.Zero);
- Thread.Sleep(2000);
- }
- finally
- {
- TDengine.Close(conn);
- }
-
- }
-
- static void QueryCallback(IntPtr param, IntPtr taosRes, int code)
- {
- if (code == 0 && taosRes != IntPtr.Zero)
- {
- FetchRawBlockAsyncCallback fetchRowAsyncCallback = new FetchRawBlockAsyncCallback(FetchRawBlockCallback);
- TDengine.FetchRawBlockAsync(taosRes, fetchRowAsyncCallback, param);
- }
- else
- {
- throw new Exception($"async query data failed,code:{code},reason:{TDengine.Error(taosRes)}");
- }
- }
-
- // Iteratively call this interface until "numOfRows" is no greater than 0.
- static void FetchRawBlockCallback(IntPtr param, IntPtr taosRes, int numOfRows)
- {
- if (numOfRows > 0)
- {
- Console.WriteLine($"{numOfRows} rows async retrieved");
- IntPtr pdata = TDengine.GetRawBlock(taosRes);
- List metaList = TDengine.FetchFields(taosRes);
- List