This is an automated email from the ASF dual-hosted git repository.
critas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iotdb-docs.git
The following commit(s) were added to refs/heads/main by this push:
new 9d09ea6e Add c sharp native api to table model (#665)
9d09ea6e is described below
commit 9d09ea6e779edb6f7f09bcce820ee24a2ab07099
Author: leto-b <[email protected]>
AuthorDate: Fri Mar 28 10:09:42 2025 +0800
Add c sharp native api to table model (#665)
* add table csharp native api
* add csharp native api sidebar
---
src/.vuepress/sidebar/V2.0.x/en-Table.ts | 1 +
src/.vuepress/sidebar/V2.0.x/zh-Table.ts | 1 +
src/.vuepress/sidebar_timecho/V2.0.x/en-Table.ts | 1 +
src/.vuepress/sidebar_timecho/V2.0.x/zh-Table.ts | 1 +
.../Table/API/Programming-CSharp-Native-API.md | 401 +++++++++++++++++++++
.../API/Programming-CSharp-Native-API.md | 401 +++++++++++++++++++++
.../Table/API/Programming-CSharp-Native-API.md | 401 +++++++++++++++++++++
.../API/Programming-CSharp-Native-API.md | 401 +++++++++++++++++++++
8 files changed, 1608 insertions(+)
diff --git a/src/.vuepress/sidebar/V2.0.x/en-Table.ts
b/src/.vuepress/sidebar/V2.0.x/en-Table.ts
index 0525331d..c18104d3 100644
--- a/src/.vuepress/sidebar/V2.0.x/en-Table.ts
+++ b/src/.vuepress/sidebar/V2.0.x/en-Table.ts
@@ -122,6 +122,7 @@ export const enSidebar = {
{ text: 'Java Native API', link: 'Programming-Java-Native-API_apache'
},
{ text: 'Python Native API', link: 'Programming-Python-Native-API' },
{ text: 'C++ Native API', link: 'Programming-Cpp-Native-API' },
+ { text: 'C# Native API', link: 'Programming-CSharp-Native-API' },
{ text: 'JDBC', link: 'Programming-JDBC_apache' },
{ text: 'RESTAPI V1 ', link: 'RestAPI-V1' },
],
diff --git a/src/.vuepress/sidebar/V2.0.x/zh-Table.ts
b/src/.vuepress/sidebar/V2.0.x/zh-Table.ts
index d82b8605..b8216372 100644
--- a/src/.vuepress/sidebar/V2.0.x/zh-Table.ts
+++ b/src/.vuepress/sidebar/V2.0.x/zh-Table.ts
@@ -114,6 +114,7 @@ export const zhSidebar = {
{ text: 'Java原生接口', link: 'Programming-Java-Native-API_apache' },
{ text: 'Python原生接口', link: 'Programming-Python-Native-API' },
{ text: 'C++原生接口', link: 'Programming-Cpp-Native-API' },
+ { text: 'C#原生接口', link: 'Programming-CSharp-Native-API' },
{ text: 'JDBC', link: 'Programming-JDBC_apache' },
{ text: 'RESTAPI V1 ', link: 'RestServiceV1' },
],
diff --git a/src/.vuepress/sidebar_timecho/V2.0.x/en-Table.ts
b/src/.vuepress/sidebar_timecho/V2.0.x/en-Table.ts
index 86b3c435..43ebeac3 100644
--- a/src/.vuepress/sidebar_timecho/V2.0.x/en-Table.ts
+++ b/src/.vuepress/sidebar_timecho/V2.0.x/en-Table.ts
@@ -127,6 +127,7 @@ export const enSidebar = {
{ text: 'Java Native API', link: 'Programming-Java-Native-API_timecho'
},
{ text: 'Python Native API', link: 'Programming-Python-Native-API' },
{ text: 'C++ Native API', link: 'Programming-Cpp-Native-API' },
+ { text: 'C# Native API', link: 'Programming-CSharp-Native-API' },
{ text: 'JDBC', link: 'Programming-JDBC_timecho' },
{ text: 'RESTAPI V1 ', link: 'RestAPI-V1' },
],
diff --git a/src/.vuepress/sidebar_timecho/V2.0.x/zh-Table.ts
b/src/.vuepress/sidebar_timecho/V2.0.x/zh-Table.ts
index 63aa0c86..215fe2d7 100644
--- a/src/.vuepress/sidebar_timecho/V2.0.x/zh-Table.ts
+++ b/src/.vuepress/sidebar_timecho/V2.0.x/zh-Table.ts
@@ -118,6 +118,7 @@ export const zhSidebar = {
{ text: 'Java原生接口', link: 'Programming-Java-Native-API_timecho' },
{ text: 'Python原生接口', link: 'Programming-Python-Native-API' },
{ text: 'C++原生接口', link: 'Programming-Cpp-Native-API' },
+ { text: 'C#原生接口', link: 'Programming-CSharp-Native-API' },
{ text: 'JDBC', link: 'Programming-JDBC_timecho' },
{ text: 'RESTAPI V1 ', link: 'RestServiceV1' },
],
diff --git a/src/UserGuide/Master/Table/API/Programming-CSharp-Native-API.md
b/src/UserGuide/Master/Table/API/Programming-CSharp-Native-API.md
new file mode 100644
index 00000000..11e3d1c7
--- /dev/null
+++ b/src/UserGuide/Master/Table/API/Programming-CSharp-Native-API.md
@@ -0,0 +1,401 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+## 1. Feature Overview
+
+IoTDB provides a C# native client driver and corresponding connection pool,
offering object-oriented interfaces that allow direct assembly of time-series
objects for writing without SQL construction. It is recommended to use the
connection pool for multi-threaded parallel database operations.
+
+## 2. Usage Instructions
+
+**Environment Requirements:**
+
+* .NET SDK >= 5.0 or .NET Framework 4.x
+* Thrift >= 0.14.1
+* NLog >= 4.7.9
+
+**Dependency Installation:**
+
+It supports installation using tools such as NuGet Package Manager or .NET
CLI. Taking .NET CLI as an example:
+
+If using .NET 5.0 or a later version of the SDK, enter the following command
to install the latest NuGet package:
+
+```Plain
+dotnet add package Apache.IoTDB
+```
+
+## 3. Read/Write Operations
+
+### 3.1 TableSessionPool
+
+#### 3.1.1 Functional Description
+
+The `TableSessionPool` defines basic operations for interacting with IoTDB,
supporting data insertion, query execution, and session closure. It also serves
as a connection pool to efficiently reuse connections and properly release
resources when unused. This interface defines how to acquire sessions from the
pool and how to close the pool.
+
+#### 3.1.2 Method List
+
+Below are the methods defined in `TableSessionPool` with detailed descriptions:
+
+| Method | Description
| Parameters
| Return Type |
+| ---------------------------------------------------------------- |
--------------------------------------------------------------------------------
|-----------------------------------------------------------------------------------------------------------|
---------------------------- |
+| `Open(bool enableRpcCompression)` | Opens a session
connection with custom `enableRpcCompression` |
`enableRpcCompression`: Whether to enable `RpcCompression` (requires
server-side configuration alignment) | `Task` |
+| `Open()` | Opens a session
connection without enabling `RpcCompression` | None
| `Task` |
+| `InsertAsync(Tablet tablet)` | Inserts a
`Tablet` object containing time-series data into the database | `tablet`:
The Tablet object to insert
| `Task<int>` |
+| `ExecuteNonQueryStatementAsync(string sql)` | Executes a
non-query SQL statement (e.g., DDL/DML commands) | `sql`:
The SQL statement to execute
| `Task<int>` |
+| `ExecuteQueryStatementAsync(string sql)` | Executes a
query SQL statement and returns a `SessionDataSet` with results | `sql`: The
SQL query to execute
| `Task<SessionDataSet>` |
+| `ExecuteQueryStatementAsync(string sql, long timeoutInMs)` | Executes a
query SQL statement with a timeout (milliseconds) | `sql`:
The SQL query to execute <br> `timeoutInMs`: Query timeout in milliseconds
| `Task<SessionDataSet>` |
+| `Close()` | Closes the
session and releases held resources | None
| `Task` |
+
+#### 3.1.3 Interface Examples
+
+```C#
+public async Task Open(bool enableRpcCompression, CancellationToken
cancellationToken = default)
+
+ public async Task Open(CancellationToken cancellationToken = default)
+
+ public async Task<int> InsertAsync(Tablet tablet)
+
+ public async Task<int> ExecuteNonQueryStatementAsync(string sql)
+
+ public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
+
+ public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql,
long timeoutInMs)
+
+ public async Task Close()
+```
+
+### 3.2 TableSessionPool.Builder
+
+#### 3.2.1 Functional Description
+
+The `TableSessionPool.Builder` class configures and creates instances of
`TableSessionPool`, allowing developers to set connection parameters, session
settings, and pooling behaviors.
+
+#### 3.2.2 Configuration Options
+
+Below are the available configuration options for `TableSessionPool.Builder`
and their defaults:
+
+| **Configuration Method** | **Description**
| **Default Value** |
+| --------------------------------------------- |
--------------------------------------------------------------------------------
| --------------------------- |
+| `SetHost(string host)` | Sets the IoTDB node host
| `localhost` |
+| `SetPort(int port)` | Sets the IoTDB node port
| `6667` |
+| `SetNodeUrls(List nodeUrls)` | Sets IoTDB cluster node URLs
(overrides `SetHost`/`SetPort` when used) | Not set |
+| `SetUsername(string username)` | Sets the connection username
| `"root"` |
+| `SetPassword(string password)` | Sets the connection password
| `"root"` |
+| `SetFetchSize(int fetchSize)` | Sets the fetch size for query
results | `1024` |
+| `SetZoneId(string zoneId)` | Sets the timezone ZoneID
| `UTC+08:00` |
+| `SetPoolSize(int poolSize)` | Sets the maximum number of
sessions in the connection pool | `8` |
+| `SetEnableRpcCompression(bool enable)` | Enables/disables RPC compression
| `false` |
+| `SetConnectionTimeoutInMs(int timeout)` | Sets the connection timeout in
milliseconds | `500` |
+| `SetDatabase(string database)` | Sets the target database name
| `""` |
+
+#### 3.2.3 Interface Examples
+
+```c#
+public Builder SetHost(string host)
+ {
+ _host = host;
+ return this;
+ }
+
+ public Builder SetPort(int port)
+ {
+ _port = port;
+ return this;
+ }
+
+ public Builder SetUsername(string username)
+ {
+ _username = username;
+ return this;
+ }
+
+ public Builder SetPassword(string password)
+ {
+ _password = password;
+ return this;
+ }
+
+ public Builder SetFetchSize(int fetchSize)
+ {
+ _fetchSize = fetchSize;
+ return this;
+ }
+
+ public Builder SetZoneId(string zoneId)
+ {
+ _zoneId = zoneId;
+ return this;
+ }
+
+ public Builder SetPoolSize(int poolSize)
+ {
+ _poolSize = poolSize;
+ return this;
+ }
+
+ public Builder SetEnableRpcCompression(bool enableRpcCompression)
+ {
+ _enableRpcCompression = enableRpcCompression;
+ return this;
+ }
+
+ public Builder SetConnectionTimeoutInMs(int timeout)
+ {
+ _connectionTimeoutInMs = timeout;
+ return this;
+ }
+
+ public Builder SetNodeUrls(List<string> nodeUrls)
+ {
+ _nodeUrls = nodeUrls;
+ return this;
+ }
+
+ protected internal Builder SetSqlDialect(string sqlDialect)
+ {
+ _sqlDialect = sqlDialect;
+ return this;
+ }
+
+ public Builder SetDatabase(string database)
+ {
+ _database = database;
+ return this;
+ }
+
+ public Builder()
+ {
+ _host = "localhost";
+ _port = 6667;
+ _username = "root";
+ _password = "root";
+ _fetchSize = 1024;
+ _zoneId = "UTC+08:00";
+ _poolSize = 8;
+ _enableRpcCompression = false;
+ _connectionTimeoutInMs = 500;
+ _sqlDialect = IoTDBConstant.TABLE_SQL_DIALECT;
+ _database = "";
+ }
+
+ public TableSessionPool Build()
+ {
+ SessionPool sessionPool;
+ // if nodeUrls is not empty, use nodeUrls to create session pool
+ if (_nodeUrls.Count > 0)
+ {
+ sessionPool = new SessionPool(_nodeUrls, _username, _password,
_fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs,
_sqlDialect, _database);
+ }
+ else
+ {
+ sessionPool = new SessionPool(_host, _port, _username, _password,
_fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs,
_sqlDialect, _database);
+ }
+ return new TableSessionPool(sessionPool);
+ }
+```
+
+## 4. Example
+
+Complete example :
[samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs](https://github.com/apache/iotdb-client-csharp/blob/main/samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs)
+
+```c#
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Apache.IoTDB.DataStructure;
+
+namespace Apache.IoTDB.Samples;
+
+public class TableSessionPoolTest
+{
+ private readonly SessionPoolTest sessionPoolTest;
+
+ public TableSessionPoolTest(SessionPoolTest sessionPoolTest)
+ {
+ this.sessionPoolTest = sessionPoolTest;
+ }
+
+ public async Task Test()
+ {
+ await TestCleanup();
+
+ await TestSelectAndInsert();
+ await TestUseDatabase();
+ // await TestCleanup();
+ }
+
+
+ public async Task TestSelectAndInsert()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE
test1");
+ await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE
test2");
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+
+ // or use full qualified table name
+ await tableSessionPool.ExecuteNonQueryStatementAsync(
+ "create table test1.table1(region_id STRING TAG, plant_id STRING TAG,
device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity
DOUBLE FIELD) with (TTL=3600000)");
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync(
+ "create table table2(region_id STRING TAG, plant_id STRING TAG, color
STRING ATTRIBUTE, temperature FLOAT FIELD, speed DOUBLE FIELD) with
(TTL=6600000)");
+
+ // show tables from current database
+ var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ // show tables by specifying another database
+ // using SHOW tables FROM
+ res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES FROM
test1");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ var tableName = "testTable1";
+ List<string> columnNames =
+ new List<string> {
+ "region_id",
+ "plant_id",
+ "device_id",
+ "model",
+ "temperature",
+ "humidity" };
+ List<TSDataType> dataTypes =
+ new List<TSDataType>{
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE};
+ List<ColumnCategory> columnCategories =
+ new List<ColumnCategory>{
+ ColumnCategory.TAG,
+ ColumnCategory.TAG,
+ ColumnCategory.TAG,
+ ColumnCategory.ATTRIBUTE,
+ ColumnCategory.FIELD,
+ ColumnCategory.FIELD};
+ var values = new List<List<object>> { };
+ var timestamps = new List<long> { };
+ for (long timestamp = 0; timestamp < 100; timestamp++)
+ {
+ timestamps.Add(timestamp);
+ values.Add(new List<object> { "1", "5", "3", "A", 1.23F + timestamp,
111.1 + timestamp });
+ }
+ var tablet = new Tablet(tableName, columnNames, columnCategories,
dataTypes, values, timestamps);
+
+ await tableSessionPool.InsertAsync(tablet);
+
+
+ res = await tableSessionPool.ExecuteQueryStatementAsync("select * from
testTable1 "
+ + "where region_id = '1' and plant_id in ('3', '5') and device_id =
'3'");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.Close();
+ }
+
+
+ public async Task TestUseDatabase()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetDatabase("test1")
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+
+ // show tables from current database
+ var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+
+ // show tables from current database
+ res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.Close();
+ }
+
+ public async Task TestCleanup()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("drop database
test1");
+ await tableSessionPool.ExecuteNonQueryStatementAsync("drop database
test2");
+
+ await tableSessionPool.Close();
+ }
+}
+```
diff --git a/src/UserGuide/latest-Table/API/Programming-CSharp-Native-API.md
b/src/UserGuide/latest-Table/API/Programming-CSharp-Native-API.md
new file mode 100644
index 00000000..11e3d1c7
--- /dev/null
+++ b/src/UserGuide/latest-Table/API/Programming-CSharp-Native-API.md
@@ -0,0 +1,401 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+## 1. Feature Overview
+
+IoTDB provides a C# native client driver and corresponding connection pool,
offering object-oriented interfaces that allow direct assembly of time-series
objects for writing without SQL construction. It is recommended to use the
connection pool for multi-threaded parallel database operations.
+
+## 2. Usage Instructions
+
+**Environment Requirements:**
+
+* .NET SDK >= 5.0 or .NET Framework 4.x
+* Thrift >= 0.14.1
+* NLog >= 4.7.9
+
+**Dependency Installation:**
+
+It supports installation using tools such as NuGet Package Manager or .NET
CLI. Taking .NET CLI as an example:
+
+If using .NET 5.0 or a later version of the SDK, enter the following command
to install the latest NuGet package:
+
+```Plain
+dotnet add package Apache.IoTDB
+```
+
+## 3. Read/Write Operations
+
+### 3.1 TableSessionPool
+
+#### 3.1.1 Functional Description
+
+The `TableSessionPool` defines basic operations for interacting with IoTDB,
supporting data insertion, query execution, and session closure. It also serves
as a connection pool to efficiently reuse connections and properly release
resources when unused. This interface defines how to acquire sessions from the
pool and how to close the pool.
+
+#### 3.1.2 Method List
+
+Below are the methods defined in `TableSessionPool` with detailed descriptions:
+
+| Method | Description
| Parameters
| Return Type |
+| ---------------------------------------------------------------- |
--------------------------------------------------------------------------------
|-----------------------------------------------------------------------------------------------------------|
---------------------------- |
+| `Open(bool enableRpcCompression)` | Opens a session
connection with custom `enableRpcCompression` |
`enableRpcCompression`: Whether to enable `RpcCompression` (requires
server-side configuration alignment) | `Task` |
+| `Open()` | Opens a session
connection without enabling `RpcCompression` | None
| `Task` |
+| `InsertAsync(Tablet tablet)` | Inserts a
`Tablet` object containing time-series data into the database | `tablet`:
The Tablet object to insert
| `Task<int>` |
+| `ExecuteNonQueryStatementAsync(string sql)` | Executes a
non-query SQL statement (e.g., DDL/DML commands) | `sql`:
The SQL statement to execute
| `Task<int>` |
+| `ExecuteQueryStatementAsync(string sql)` | Executes a
query SQL statement and returns a `SessionDataSet` with results | `sql`: The
SQL query to execute
| `Task<SessionDataSet>` |
+| `ExecuteQueryStatementAsync(string sql, long timeoutInMs)` | Executes a
query SQL statement with a timeout (milliseconds) | `sql`:
The SQL query to execute <br> `timeoutInMs`: Query timeout in milliseconds
| `Task<SessionDataSet>` |
+| `Close()` | Closes the
session and releases held resources | None
| `Task` |
+
+#### 3.1.3 Interface Examples
+
+```C#
+public async Task Open(bool enableRpcCompression, CancellationToken
cancellationToken = default)
+
+ public async Task Open(CancellationToken cancellationToken = default)
+
+ public async Task<int> InsertAsync(Tablet tablet)
+
+ public async Task<int> ExecuteNonQueryStatementAsync(string sql)
+
+ public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
+
+ public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql,
long timeoutInMs)
+
+ public async Task Close()
+```
+
+### 3.2 TableSessionPool.Builder
+
+#### 3.2.1 Functional Description
+
+The `TableSessionPool.Builder` class configures and creates instances of
`TableSessionPool`, allowing developers to set connection parameters, session
settings, and pooling behaviors.
+
+#### 3.2.2 Configuration Options
+
+Below are the available configuration options for `TableSessionPool.Builder`
and their defaults:
+
+| **Configuration Method** | **Description**
| **Default Value** |
+| --------------------------------------------- |
--------------------------------------------------------------------------------
| --------------------------- |
+| `SetHost(string host)` | Sets the IoTDB node host
| `localhost` |
+| `SetPort(int port)` | Sets the IoTDB node port
| `6667` |
+| `SetNodeUrls(List nodeUrls)` | Sets IoTDB cluster node URLs
(overrides `SetHost`/`SetPort` when used) | Not set |
+| `SetUsername(string username)` | Sets the connection username
| `"root"` |
+| `SetPassword(string password)` | Sets the connection password
| `"root"` |
+| `SetFetchSize(int fetchSize)` | Sets the fetch size for query
results | `1024` |
+| `SetZoneId(string zoneId)` | Sets the timezone ZoneID
| `UTC+08:00` |
+| `SetPoolSize(int poolSize)` | Sets the maximum number of
sessions in the connection pool | `8` |
+| `SetEnableRpcCompression(bool enable)` | Enables/disables RPC compression
| `false` |
+| `SetConnectionTimeoutInMs(int timeout)` | Sets the connection timeout in
milliseconds | `500` |
+| `SetDatabase(string database)` | Sets the target database name
| `""` |
+
+#### 3.2.3 Interface Examples
+
+```c#
+public Builder SetHost(string host)
+ {
+ _host = host;
+ return this;
+ }
+
+ public Builder SetPort(int port)
+ {
+ _port = port;
+ return this;
+ }
+
+ public Builder SetUsername(string username)
+ {
+ _username = username;
+ return this;
+ }
+
+ public Builder SetPassword(string password)
+ {
+ _password = password;
+ return this;
+ }
+
+ public Builder SetFetchSize(int fetchSize)
+ {
+ _fetchSize = fetchSize;
+ return this;
+ }
+
+ public Builder SetZoneId(string zoneId)
+ {
+ _zoneId = zoneId;
+ return this;
+ }
+
+ public Builder SetPoolSize(int poolSize)
+ {
+ _poolSize = poolSize;
+ return this;
+ }
+
+ public Builder SetEnableRpcCompression(bool enableRpcCompression)
+ {
+ _enableRpcCompression = enableRpcCompression;
+ return this;
+ }
+
+ public Builder SetConnectionTimeoutInMs(int timeout)
+ {
+ _connectionTimeoutInMs = timeout;
+ return this;
+ }
+
+ public Builder SetNodeUrls(List<string> nodeUrls)
+ {
+ _nodeUrls = nodeUrls;
+ return this;
+ }
+
+ protected internal Builder SetSqlDialect(string sqlDialect)
+ {
+ _sqlDialect = sqlDialect;
+ return this;
+ }
+
+ public Builder SetDatabase(string database)
+ {
+ _database = database;
+ return this;
+ }
+
+ public Builder()
+ {
+ _host = "localhost";
+ _port = 6667;
+ _username = "root";
+ _password = "root";
+ _fetchSize = 1024;
+ _zoneId = "UTC+08:00";
+ _poolSize = 8;
+ _enableRpcCompression = false;
+ _connectionTimeoutInMs = 500;
+ _sqlDialect = IoTDBConstant.TABLE_SQL_DIALECT;
+ _database = "";
+ }
+
+ public TableSessionPool Build()
+ {
+ SessionPool sessionPool;
+ // if nodeUrls is not empty, use nodeUrls to create session pool
+ if (_nodeUrls.Count > 0)
+ {
+ sessionPool = new SessionPool(_nodeUrls, _username, _password,
_fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs,
_sqlDialect, _database);
+ }
+ else
+ {
+ sessionPool = new SessionPool(_host, _port, _username, _password,
_fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs,
_sqlDialect, _database);
+ }
+ return new TableSessionPool(sessionPool);
+ }
+```
+
+## 4. Example
+
+Complete example :
[samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs](https://github.com/apache/iotdb-client-csharp/blob/main/samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs)
+
+```c#
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Apache.IoTDB.DataStructure;
+
+namespace Apache.IoTDB.Samples;
+
+public class TableSessionPoolTest
+{
+ private readonly SessionPoolTest sessionPoolTest;
+
+ public TableSessionPoolTest(SessionPoolTest sessionPoolTest)
+ {
+ this.sessionPoolTest = sessionPoolTest;
+ }
+
+ public async Task Test()
+ {
+ await TestCleanup();
+
+ await TestSelectAndInsert();
+ await TestUseDatabase();
+ // await TestCleanup();
+ }
+
+
+ public async Task TestSelectAndInsert()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE
test1");
+ await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE
test2");
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+
+ // or use full qualified table name
+ await tableSessionPool.ExecuteNonQueryStatementAsync(
+ "create table test1.table1(region_id STRING TAG, plant_id STRING TAG,
device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity
DOUBLE FIELD) with (TTL=3600000)");
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync(
+ "create table table2(region_id STRING TAG, plant_id STRING TAG, color
STRING ATTRIBUTE, temperature FLOAT FIELD, speed DOUBLE FIELD) with
(TTL=6600000)");
+
+ // show tables from current database
+ var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ // show tables by specifying another database
+ // using SHOW tables FROM
+ res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES FROM
test1");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ var tableName = "testTable1";
+ List<string> columnNames =
+ new List<string> {
+ "region_id",
+ "plant_id",
+ "device_id",
+ "model",
+ "temperature",
+ "humidity" };
+ List<TSDataType> dataTypes =
+ new List<TSDataType>{
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE};
+ List<ColumnCategory> columnCategories =
+ new List<ColumnCategory>{
+ ColumnCategory.TAG,
+ ColumnCategory.TAG,
+ ColumnCategory.TAG,
+ ColumnCategory.ATTRIBUTE,
+ ColumnCategory.FIELD,
+ ColumnCategory.FIELD};
+ var values = new List<List<object>> { };
+ var timestamps = new List<long> { };
+ for (long timestamp = 0; timestamp < 100; timestamp++)
+ {
+ timestamps.Add(timestamp);
+ values.Add(new List<object> { "1", "5", "3", "A", 1.23F + timestamp,
111.1 + timestamp });
+ }
+ var tablet = new Tablet(tableName, columnNames, columnCategories,
dataTypes, values, timestamps);
+
+ await tableSessionPool.InsertAsync(tablet);
+
+
+ res = await tableSessionPool.ExecuteQueryStatementAsync("select * from
testTable1 "
+ + "where region_id = '1' and plant_id in ('3', '5') and device_id =
'3'");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.Close();
+ }
+
+
+ public async Task TestUseDatabase()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetDatabase("test1")
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+
+ // show tables from current database
+ var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+
+ // show tables from current database
+ res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.Close();
+ }
+
+ public async Task TestCleanup()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("drop database
test1");
+ await tableSessionPool.ExecuteNonQueryStatementAsync("drop database
test2");
+
+ await tableSessionPool.Close();
+ }
+}
+```
diff --git a/src/zh/UserGuide/Master/Table/API/Programming-CSharp-Native-API.md
b/src/zh/UserGuide/Master/Table/API/Programming-CSharp-Native-API.md
new file mode 100644
index 00000000..bd69fb2c
--- /dev/null
+++ b/src/zh/UserGuide/Master/Table/API/Programming-CSharp-Native-API.md
@@ -0,0 +1,401 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+## 1. 功能介绍
+
+IoTDB具备C#原生客户端驱动和对应的连接池,提供对象化接口,可以直接组装时序对象进行写入,无需拼装 SQL。推荐使用连接池,多线程并行操作数据库。
+
+## 2. 使用方式
+
+**环境要求:**
+
+* .NET SDK >= 5.0 或 .NET Framework 4.x
+* Thrift >= 0.14.1
+* NLog >= 4.7.9
+
+**依赖安装:**
+
+支持使用 NuGet Package Manager, .NET CLI等工具来安装,以 .NET CLI为例
+
+如果使用的是\\.NET 5.0 或者更高版本的SDK,输入如下命令即可安装最新的NuGet包
+
+```Plain
+dotnet add package Apache.IoTDB
+```
+
+## 3. 读写操作
+
+### 3.1 TableSessionPool
+
+#### 3.1.1 功能描述
+
+TableSessionPool
定义了与IoTDB交互的基本操作,可以执行数据插入、查询操作以及关闭会话等,同时也是一个连接池这个池可以帮助我们高效地重用连接,并且在不需要时正确地清理资源,
该接口定义了如何从池中获取会话以及如何关闭池的基本操作。
+
+#### 3.1.2 方法列表
+
+以下是 TableSessionPool 中定义的方法及其详细说明:
+
+| 方法 | 描述
| 参数
| 返回值 |
+| ---------------------------------------------------------------- |
----------------------------------------------------------------
|-------------------------------------------------------------------|--------------------|
+| `Open(bool enableRpcCompression)` |
打开会话连接,自定义`enableRpcCompression` |
`enableRpcCompression`:是否启用`RpcCompression`,此参数需配合 Server 端配置一同使用 | `Task`
|
+| `Open()` |
打开会话连接,不开启`RpcCompression` | 无
| `Task` |
+| `InsertAsync(Tablet tablet)` |
将一个包含时间序列数据的Tablet 对象插入到数据库中 | tablet: 要插入的Tablet对象
| `Task<int>` |
+| `ExecuteNonQueryStatementAsync(string sql)` |
执行非查询SQL语句,如DDL(数据定义语言)或DML(数据操作语言)命令 | sql: 要执行的SQL语句。
| `Task<int>` |
+| `ExecuteQueryStatementAsync(string sql)` |
执行查询SQL语句,并返回包含查询结果的SessionDataSet对象 | sql: 要执行的SQL语句。
| `Task<SessionDataSet>` |
+| `ExecuteQueryStatementAsync(string sql, long timeoutInMs)` |
执行查询SQL语句,并设置查询超时时间(以毫秒为单位) | sql: 要执行的查询SQL语句。<br>timeoutInMs:
查询超时时间(毫秒) | `Task<SessionDataSet>` |
+| `Close()` | 关闭会话,释放所持有的资源
| 无
| `Task` |
+
+#### 3.1.3 接口展示
+
+```C#
+public async Task Open(bool enableRpcCompression, CancellationToken
cancellationToken = default)
+
+ public async Task Open(CancellationToken cancellationToken = default)
+
+ public async Task<int> InsertAsync(Tablet tablet)
+
+ public async Task<int> ExecuteNonQueryStatementAsync(string sql)
+
+ public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
+
+ public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql,
long timeoutInMs)
+
+ public async Task Close()
+```
+
+### 3.2 TableSessionPool.Builder
+
+#### 3.2.1 功能描述
+
+TableSessionPool.Builder 是 TableSessionPool的构造器,用于配置和创建 TableSessionPool
的实例。允许开发者配置连接参数、会话参数和池化行为等。
+
+#### 3.2.2 配置选项
+
+以下是 TableSessionPool.Builder 类的可用配置选项及其默认值:
+
+| **配置项** | **描述**
| **默认值** |
+| ---------------------------------------------------- |
---------------------------------------------------------------- |
------------------ |
+| `SetHost(string host)` | 设置IoTDB的节点 host
| `localhost` |
+| `SetPort(int port)` | 设置IoTDB的节点端口
| `6667` |
+| `SetNodeUrls(List nodeUrls)` |
设置IoTDB集群的节点URL列表,当设置此项时会忽略SetHost和SetPort | `无 ` |
+| `SetUsername(string username)` | 设置连接的用户名
| `"root"` |
+| `SetPassword(string password)` | 设置连接的密码
| `"root" ` |
+| `SetFetchSize(int fetchSize)` | 设置查询结果的获取大小
| `1024 ` |
+| `SetZoneId(string zoneId)` | 设置时区相关的ZoneId
| `UTC+08:00` |
+| `SetPoolSize(int poolSize)` |
设置会话池的最大大小,即池中允许的最大会话数 | `8 ` |
+| `SetEnableRpcCompression(bool enableRpcCompression)` | 是否启用RPC压缩
| `false` |
+| `SetConnectionTimeoutInMs(int timeout)` | 设置连接超时时间(毫秒)
| `500` |
+| `SetDatabase(string database)` | 设置目标数据库名称
|` "" ` |
+
+#### 3.2.3 接口展示
+
+```c#
+public Builder SetHost(string host)
+ {
+ _host = host;
+ return this;
+ }
+
+ public Builder SetPort(int port)
+ {
+ _port = port;
+ return this;
+ }
+
+ public Builder SetUsername(string username)
+ {
+ _username = username;
+ return this;
+ }
+
+ public Builder SetPassword(string password)
+ {
+ _password = password;
+ return this;
+ }
+
+ public Builder SetFetchSize(int fetchSize)
+ {
+ _fetchSize = fetchSize;
+ return this;
+ }
+
+ public Builder SetZoneId(string zoneId)
+ {
+ _zoneId = zoneId;
+ return this;
+ }
+
+ public Builder SetPoolSize(int poolSize)
+ {
+ _poolSize = poolSize;
+ return this;
+ }
+
+ public Builder SetEnableRpcCompression(bool enableRpcCompression)
+ {
+ _enableRpcCompression = enableRpcCompression;
+ return this;
+ }
+
+ public Builder SetConnectionTimeoutInMs(int timeout)
+ {
+ _connectionTimeoutInMs = timeout;
+ return this;
+ }
+
+ public Builder SetNodeUrls(List<string> nodeUrls)
+ {
+ _nodeUrls = nodeUrls;
+ return this;
+ }
+
+ protected internal Builder SetSqlDialect(string sqlDialect)
+ {
+ _sqlDialect = sqlDialect;
+ return this;
+ }
+
+ public Builder SetDatabase(string database)
+ {
+ _database = database;
+ return this;
+ }
+
+ public Builder()
+ {
+ _host = "localhost";
+ _port = 6667;
+ _username = "root";
+ _password = "root";
+ _fetchSize = 1024;
+ _zoneId = "UTC+08:00";
+ _poolSize = 8;
+ _enableRpcCompression = false;
+ _connectionTimeoutInMs = 500;
+ _sqlDialect = IoTDBConstant.TABLE_SQL_DIALECT;
+ _database = "";
+ }
+
+ public TableSessionPool Build()
+ {
+ SessionPool sessionPool;
+ // if nodeUrls is not empty, use nodeUrls to create session pool
+ if (_nodeUrls.Count > 0)
+ {
+ sessionPool = new SessionPool(_nodeUrls, _username, _password,
_fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs,
_sqlDialect, _database);
+ }
+ else
+ {
+ sessionPool = new SessionPool(_host, _port, _username, _password,
_fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs,
_sqlDialect, _database);
+ }
+ return new TableSessionPool(sessionPool);
+ }
+```
+
+## 4. 示例代码
+
+完整示例:[samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs](https://github.com/apache/iotdb-client-csharp/blob/main/samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs)
+
+```c#
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Apache.IoTDB.DataStructure;
+
+namespace Apache.IoTDB.Samples;
+
+public class TableSessionPoolTest
+{
+ private readonly SessionPoolTest sessionPoolTest;
+
+ public TableSessionPoolTest(SessionPoolTest sessionPoolTest)
+ {
+ this.sessionPoolTest = sessionPoolTest;
+ }
+
+ public async Task Test()
+ {
+ await TestCleanup();
+
+ await TestSelectAndInsert();
+ await TestUseDatabase();
+ // await TestCleanup();
+ }
+
+
+ public async Task TestSelectAndInsert()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE
test1");
+ await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE
test2");
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+
+ // or use full qualified table name
+ await tableSessionPool.ExecuteNonQueryStatementAsync(
+ "create table test1.table1(region_id STRING TAG, plant_id STRING TAG,
device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity
DOUBLE FIELD) with (TTL=3600000)");
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync(
+ "create table table2(region_id STRING TAG, plant_id STRING TAG, color
STRING ATTRIBUTE, temperature FLOAT FIELD, speed DOUBLE FIELD) with
(TTL=6600000)");
+
+ // show tables from current database
+ var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ // show tables by specifying another database
+ // using SHOW tables FROM
+ res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES FROM
test1");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ var tableName = "testTable1";
+ List<string> columnNames =
+ new List<string> {
+ "region_id",
+ "plant_id",
+ "device_id",
+ "model",
+ "temperature",
+ "humidity" };
+ List<TSDataType> dataTypes =
+ new List<TSDataType>{
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE};
+ List<ColumnCategory> columnCategories =
+ new List<ColumnCategory>{
+ ColumnCategory.TAG,
+ ColumnCategory.TAG,
+ ColumnCategory.TAG,
+ ColumnCategory.ATTRIBUTE,
+ ColumnCategory.FIELD,
+ ColumnCategory.FIELD};
+ var values = new List<List<object>> { };
+ var timestamps = new List<long> { };
+ for (long timestamp = 0; timestamp < 100; timestamp++)
+ {
+ timestamps.Add(timestamp);
+ values.Add(new List<object> { "1", "5", "3", "A", 1.23F + timestamp,
111.1 + timestamp });
+ }
+ var tablet = new Tablet(tableName, columnNames, columnCategories,
dataTypes, values, timestamps);
+
+ await tableSessionPool.InsertAsync(tablet);
+
+
+ res = await tableSessionPool.ExecuteQueryStatementAsync("select * from
testTable1 "
+ + "where region_id = '1' and plant_id in ('3', '5') and device_id =
'3'");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.Close();
+ }
+
+
+ public async Task TestUseDatabase()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetDatabase("test1")
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+
+ // show tables from current database
+ var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+
+ // show tables from current database
+ res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.Close();
+ }
+
+ public async Task TestCleanup()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("drop database
test1");
+ await tableSessionPool.ExecuteNonQueryStatementAsync("drop database
test2");
+
+ await tableSessionPool.Close();
+ }
+}
+```
diff --git a/src/zh/UserGuide/latest-Table/API/Programming-CSharp-Native-API.md
b/src/zh/UserGuide/latest-Table/API/Programming-CSharp-Native-API.md
new file mode 100644
index 00000000..bd69fb2c
--- /dev/null
+++ b/src/zh/UserGuide/latest-Table/API/Programming-CSharp-Native-API.md
@@ -0,0 +1,401 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+## 1. 功能介绍
+
+IoTDB具备C#原生客户端驱动和对应的连接池,提供对象化接口,可以直接组装时序对象进行写入,无需拼装 SQL。推荐使用连接池,多线程并行操作数据库。
+
+## 2. 使用方式
+
+**环境要求:**
+
+* .NET SDK >= 5.0 或 .NET Framework 4.x
+* Thrift >= 0.14.1
+* NLog >= 4.7.9
+
+**依赖安装:**
+
+支持使用 NuGet Package Manager, .NET CLI等工具来安装,以 .NET CLI为例
+
+如果使用的是\\.NET 5.0 或者更高版本的SDK,输入如下命令即可安装最新的NuGet包
+
+```Plain
+dotnet add package Apache.IoTDB
+```
+
+## 3. 读写操作
+
+### 3.1 TableSessionPool
+
+#### 3.1.1 功能描述
+
+TableSessionPool
定义了与IoTDB交互的基本操作,可以执行数据插入、查询操作以及关闭会话等,同时也是一个连接池这个池可以帮助我们高效地重用连接,并且在不需要时正确地清理资源,
该接口定义了如何从池中获取会话以及如何关闭池的基本操作。
+
+#### 3.1.2 方法列表
+
+以下是 TableSessionPool 中定义的方法及其详细说明:
+
+| 方法 | 描述
| 参数
| 返回值 |
+| ---------------------------------------------------------------- |
----------------------------------------------------------------
|-------------------------------------------------------------------|--------------------|
+| `Open(bool enableRpcCompression)` |
打开会话连接,自定义`enableRpcCompression` |
`enableRpcCompression`:是否启用`RpcCompression`,此参数需配合 Server 端配置一同使用 | `Task`
|
+| `Open()` |
打开会话连接,不开启`RpcCompression` | 无
| `Task` |
+| `InsertAsync(Tablet tablet)` |
将一个包含时间序列数据的Tablet 对象插入到数据库中 | tablet: 要插入的Tablet对象
| `Task<int>` |
+| `ExecuteNonQueryStatementAsync(string sql)` |
执行非查询SQL语句,如DDL(数据定义语言)或DML(数据操作语言)命令 | sql: 要执行的SQL语句。
| `Task<int>` |
+| `ExecuteQueryStatementAsync(string sql)` |
执行查询SQL语句,并返回包含查询结果的SessionDataSet对象 | sql: 要执行的SQL语句。
| `Task<SessionDataSet>` |
+| `ExecuteQueryStatementAsync(string sql, long timeoutInMs)` |
执行查询SQL语句,并设置查询超时时间(以毫秒为单位) | sql: 要执行的查询SQL语句。<br>timeoutInMs:
查询超时时间(毫秒) | `Task<SessionDataSet>` |
+| `Close()` | 关闭会话,释放所持有的资源
| 无
| `Task` |
+
+#### 3.1.3 接口展示
+
+```C#
+public async Task Open(bool enableRpcCompression, CancellationToken
cancellationToken = default)
+
+ public async Task Open(CancellationToken cancellationToken = default)
+
+ public async Task<int> InsertAsync(Tablet tablet)
+
+ public async Task<int> ExecuteNonQueryStatementAsync(string sql)
+
+ public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
+
+ public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql,
long timeoutInMs)
+
+ public async Task Close()
+```
+
+### 3.2 TableSessionPool.Builder
+
+#### 3.2.1 功能描述
+
+TableSessionPool.Builder 是 TableSessionPool的构造器,用于配置和创建 TableSessionPool
的实例。允许开发者配置连接参数、会话参数和池化行为等。
+
+#### 3.2.2 配置选项
+
+以下是 TableSessionPool.Builder 类的可用配置选项及其默认值:
+
+| **配置项** | **描述**
| **默认值** |
+| ---------------------------------------------------- |
---------------------------------------------------------------- |
------------------ |
+| `SetHost(string host)` | 设置IoTDB的节点 host
| `localhost` |
+| `SetPort(int port)` | 设置IoTDB的节点端口
| `6667` |
+| `SetNodeUrls(List nodeUrls)` |
设置IoTDB集群的节点URL列表,当设置此项时会忽略SetHost和SetPort | `无 ` |
+| `SetUsername(string username)` | 设置连接的用户名
| `"root"` |
+| `SetPassword(string password)` | 设置连接的密码
| `"root" ` |
+| `SetFetchSize(int fetchSize)` | 设置查询结果的获取大小
| `1024 ` |
+| `SetZoneId(string zoneId)` | 设置时区相关的ZoneId
| `UTC+08:00` |
+| `SetPoolSize(int poolSize)` |
设置会话池的最大大小,即池中允许的最大会话数 | `8 ` |
+| `SetEnableRpcCompression(bool enableRpcCompression)` | 是否启用RPC压缩
| `false` |
+| `SetConnectionTimeoutInMs(int timeout)` | 设置连接超时时间(毫秒)
| `500` |
+| `SetDatabase(string database)` | 设置目标数据库名称
|` "" ` |
+
+#### 3.2.3 接口展示
+
+```c#
+public Builder SetHost(string host)
+ {
+ _host = host;
+ return this;
+ }
+
+ public Builder SetPort(int port)
+ {
+ _port = port;
+ return this;
+ }
+
+ public Builder SetUsername(string username)
+ {
+ _username = username;
+ return this;
+ }
+
+ public Builder SetPassword(string password)
+ {
+ _password = password;
+ return this;
+ }
+
+ public Builder SetFetchSize(int fetchSize)
+ {
+ _fetchSize = fetchSize;
+ return this;
+ }
+
+ public Builder SetZoneId(string zoneId)
+ {
+ _zoneId = zoneId;
+ return this;
+ }
+
+ public Builder SetPoolSize(int poolSize)
+ {
+ _poolSize = poolSize;
+ return this;
+ }
+
+ public Builder SetEnableRpcCompression(bool enableRpcCompression)
+ {
+ _enableRpcCompression = enableRpcCompression;
+ return this;
+ }
+
+ public Builder SetConnectionTimeoutInMs(int timeout)
+ {
+ _connectionTimeoutInMs = timeout;
+ return this;
+ }
+
+ public Builder SetNodeUrls(List<string> nodeUrls)
+ {
+ _nodeUrls = nodeUrls;
+ return this;
+ }
+
+ protected internal Builder SetSqlDialect(string sqlDialect)
+ {
+ _sqlDialect = sqlDialect;
+ return this;
+ }
+
+ public Builder SetDatabase(string database)
+ {
+ _database = database;
+ return this;
+ }
+
+ public Builder()
+ {
+ _host = "localhost";
+ _port = 6667;
+ _username = "root";
+ _password = "root";
+ _fetchSize = 1024;
+ _zoneId = "UTC+08:00";
+ _poolSize = 8;
+ _enableRpcCompression = false;
+ _connectionTimeoutInMs = 500;
+ _sqlDialect = IoTDBConstant.TABLE_SQL_DIALECT;
+ _database = "";
+ }
+
+ public TableSessionPool Build()
+ {
+ SessionPool sessionPool;
+ // if nodeUrls is not empty, use nodeUrls to create session pool
+ if (_nodeUrls.Count > 0)
+ {
+ sessionPool = new SessionPool(_nodeUrls, _username, _password,
_fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs,
_sqlDialect, _database);
+ }
+ else
+ {
+ sessionPool = new SessionPool(_host, _port, _username, _password,
_fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs,
_sqlDialect, _database);
+ }
+ return new TableSessionPool(sessionPool);
+ }
+```
+
+## 4. 示例代码
+
+完整示例:[samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs](https://github.com/apache/iotdb-client-csharp/blob/main/samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs)
+
+```c#
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Apache.IoTDB.DataStructure;
+
+namespace Apache.IoTDB.Samples;
+
+public class TableSessionPoolTest
+{
+ private readonly SessionPoolTest sessionPoolTest;
+
+ public TableSessionPoolTest(SessionPoolTest sessionPoolTest)
+ {
+ this.sessionPoolTest = sessionPoolTest;
+ }
+
+ public async Task Test()
+ {
+ await TestCleanup();
+
+ await TestSelectAndInsert();
+ await TestUseDatabase();
+ // await TestCleanup();
+ }
+
+
+ public async Task TestSelectAndInsert()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE
test1");
+ await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE
test2");
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+
+ // or use full qualified table name
+ await tableSessionPool.ExecuteNonQueryStatementAsync(
+ "create table test1.table1(region_id STRING TAG, plant_id STRING TAG,
device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity
DOUBLE FIELD) with (TTL=3600000)");
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync(
+ "create table table2(region_id STRING TAG, plant_id STRING TAG, color
STRING ATTRIBUTE, temperature FLOAT FIELD, speed DOUBLE FIELD) with
(TTL=6600000)");
+
+ // show tables from current database
+ var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ // show tables by specifying another database
+ // using SHOW tables FROM
+ res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES FROM
test1");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ var tableName = "testTable1";
+ List<string> columnNames =
+ new List<string> {
+ "region_id",
+ "plant_id",
+ "device_id",
+ "model",
+ "temperature",
+ "humidity" };
+ List<TSDataType> dataTypes =
+ new List<TSDataType>{
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.STRING,
+ TSDataType.FLOAT,
+ TSDataType.DOUBLE};
+ List<ColumnCategory> columnCategories =
+ new List<ColumnCategory>{
+ ColumnCategory.TAG,
+ ColumnCategory.TAG,
+ ColumnCategory.TAG,
+ ColumnCategory.ATTRIBUTE,
+ ColumnCategory.FIELD,
+ ColumnCategory.FIELD};
+ var values = new List<List<object>> { };
+ var timestamps = new List<long> { };
+ for (long timestamp = 0; timestamp < 100; timestamp++)
+ {
+ timestamps.Add(timestamp);
+ values.Add(new List<object> { "1", "5", "3", "A", 1.23F + timestamp,
111.1 + timestamp });
+ }
+ var tablet = new Tablet(tableName, columnNames, columnCategories,
dataTypes, values, timestamps);
+
+ await tableSessionPool.InsertAsync(tablet);
+
+
+ res = await tableSessionPool.ExecuteQueryStatementAsync("select * from
testTable1 "
+ + "where region_id = '1' and plant_id in ('3', '5') and device_id =
'3'");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.Close();
+ }
+
+
+ public async Task TestUseDatabase()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetDatabase("test1")
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+
+ // show tables from current database
+ var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+
+ // show tables from current database
+ res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+ res.ShowTableNames();
+ while (res.HasNext()) Console.WriteLine(res.Next());
+ await res.Close();
+
+ await tableSessionPool.Close();
+ }
+
+ public async Task TestCleanup()
+ {
+ var tableSessionPool = new TableSessionPool.Builder()
+ .SetNodeUrls(sessionPoolTest.nodeUrls)
+ .SetUsername(sessionPoolTest.username)
+ .SetPassword(sessionPoolTest.password)
+ .SetFetchSize(1024)
+ .Build();
+
+ await tableSessionPool.Open(false);
+
+ if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+
+ await tableSessionPool.ExecuteNonQueryStatementAsync("drop database
test1");
+ await tableSessionPool.ExecuteNonQueryStatementAsync("drop database
test2");
+
+ await tableSessionPool.Close();
+ }
+}
+```