TDengine C# Client Library
TDengine.Connector
is the official C# client library for TDengine. C# developers can develop applications to access TDengine instance data.
This article describes how to install TDengine.Connector
in a Linux or Windows environment and connect to TDengine clusters via TDengine.Connector
to perform basic operations such as data writing and querying.
The source code for TDengine.Connector
is hosted on GitHub.
Version support
Please refer to version support list
Installation
Pre-installation
- Install the .NET SDK
- Nuget Client (optional installation)
- Install TDengine client driver, please refer to Install client driver for details
Add TDengine.Connector
through Nuget
dotnet add package TDengine.Connector
Establishing a connection
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
</ItemGroup>
<Target Name="copyDLLDependency" BeforeTargets="BeforeBuild">
<ItemGroup>
<DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
</Target>
</Project>
using System;
using TDengineWS.Impl;
namespace Cloud.Examples
{
public class ConnectExample
{
static void Main(string[] args)
{
string dsn = Environment.GetEnvironmentVariable("TDENGINE_CLOUD_DSN");
Connect(dsn);
}
public static void Connect(string dsn)
{
// get connect
IntPtr conn = LibTaosWS.WSConnectWithDSN(dsn);
if (conn == IntPtr.Zero)
{
throw new Exception($"get connection failed,reason:{LibTaosWS.WSErrorStr(conn)},code:{LibTaosWS.WSErrorNo(conn)}");
}
else
{
Console.WriteLine("Establish connect success.");
}
// do something ...
// close connect
LibTaosWS.WSClose(conn);
}
}
}
Usage examples
Basic Insert and Query
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
</ItemGroup>
<Target Name="copyDLLDependency" BeforeTargets="BeforeBuild">
<ItemGroup>
<DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
</Target>
</Project>
using System;
using TDengineDriver;
using TDengineWS.Impl;
using System.Collections.Generic;
namespace Cloud.Examples
{
public class UsageExample
{
static void Main(string[] args)
{
string dsn = Environment.GetEnvironmentVariable("TDENGINE_CLOUD_DSN");
IntPtr conn = Connect(dsn);
InsertData(conn);
SelectData(conn);
// close connect
LibTaosWS.WSClose(conn);
}
public static IntPtr Connect(string dsn)
{
// get connect
IntPtr conn = LibTaosWS.WSConnectWithDSN(dsn);
if (conn == IntPtr.Zero)
{
throw new Exception($"get connection failed,reason:{LibTaosWS.WSErrorStr(conn)},code:{LibTaosWS.WSErrorNo(conn)}");
}
return conn;
}
public static void InsertData(IntPtr conn)
{
string createTable = "CREATE STABLE if not exists test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)";
string insertData = "INSERT INTO " +
"test.d1001 USING test.meters TAGS('California.SanFrancisco', 1) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000)" +
"test.d1002 USING test.meters TAGS('California.SanFrancisco', 2) VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)" +
"test.d1003 USING test.meters TAGS('California.LosAngeles', 3) VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000)" +
"test.d1004 USING test.meters TAGS('California.LosAngeles', 4) VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ";
// create database under database named 'test'
IntPtr res = LibTaosWS.WSQuery(conn, createTable);
ValidQueryExecution(res);
// Free the query result every time when used up it.
LibTaosWS.WSFreeResult(res);
// insert data into the table created in previous step.
res = LibTaosWS.WSQuery(conn, insertData);
ValidQueryExecution(res);
// Free the query result every time when used up it.
LibTaosWS.WSFreeResult(res);
}
public static void SelectData(IntPtr conn)
{
string selectTable = "select * from test.meters";
IntPtr res = LibTaosWS.WSQueryTimeout(conn, selectTable,5000);
ValidQueryExecution(res);
// print meta
List<TDengineMeta> metas = LibTaosWS.WSGetFields(res);
foreach (var meta in metas)
{
Console.Write("{0} {1}({2})\t|", meta.name, meta.TypeName(), meta.size);
}
Console.WriteLine("");
List<object> dataSet = LibTaosWS.WSGetData(res);
for (int i = 0; i < dataSet.Count;)
{
for (int j = 0; j < metas.Count; j++)
{
Console.Write("{0}\t|\t", dataSet[i]);
i++;
}
Console.WriteLine("");
}
Console.WriteLine("");
// Free the query result every time when used up it.
LibTaosWS.WSFreeResult(res);
}
// Check if LibTaosWS.Query() execute correctly.
public static void ValidQueryExecution(IntPtr res)
{
int code = LibTaosWS.WSErrorNo(res);
if (code != 0)
{
throw new Exception($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(res)}, code:{code}");
}
}
}
}
STMT Insert
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="3.0.*" GeneratePathProperty="true" />
</ItemGroup>
<Target Name="copyDLLDependency" BeforeTargets="BeforeBuild">
<ItemGroup>
<DepDLLFiles Include="$(PkgTDengine_Connector)\runtimes\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(DepDLLFiles)" DestinationFolder="$(OutDir)" />
</Target>
</Project>
using System;
using TDengineWS.Impl;
using TDengineDriver;
using System.Runtime.InteropServices;
namespace Cloud.Examples
{
public class STMTExample
{
static void Main(string[] args)
{
string dsn = Environment.GetEnvironmentVariable("TDENGINE_CLOUD_DSN");
IntPtr conn = Connect(dsn);
// assume table has been created.
// CREATE STABLE if not exists test.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)
string insert = "insert into ? using test.meters tags(?,?) values(?,?,?,?)";
// Init STMT
IntPtr stmt = LibTaosWS.WSStmtInit(conn);
if (stmt != IntPtr.Zero)
{
// Prepare SQL
int code = LibTaosWS.WSStmtPrepare(stmt, insert);
ValidSTMTStep(code, stmt, "WSInit()");
// Bind child table name and tags
TAOS_MULTI_BIND[] tags = new TAOS_MULTI_BIND[2] { WSMultiBind.WSBindBinary(new string[] { "California.LosAngeles" }), WSMultiBind.WSBindInt(new int?[] { 6 }) };
code = LibTaosWS.WSStmtSetTbnameTags(stmt, "test.d1005",tags, 2);
ValidSTMTStep(code, stmt, "WSStmtSetTbnameTags()");
// bind column value
TAOS_MULTI_BIND[] data = new TAOS_MULTI_BIND[4];
data[0] = WSMultiBind.WSBindTimestamp(new long[] { 1538551000000, 1538552000000, 1538553000000, 1538554000000, 1538555000000 });
data[1] = WSMultiBind.WSBindFloat(new float?[] { 10.30000F, 10.30000F, 11.30000F, 10.30000F, 10.80000F });
data[2] = WSMultiBind.WSBindInt(new int?[] { 218, 219, 221, 222, 223 });
data[3] = WSMultiBind.WSBindFloat(new float?[] { 0.28000F, 0.29000F, 0.30000F, 0.31000F, 0.32000F });
code = LibTaosWS.WSStmtBindParamBatch(stmt, data, 4);
ValidSTMTStep(code, stmt, "WSStmtBindParamBatch");
LibTaosWS.WSStmtAddBatch(stmt);
ValidSTMTStep(code, stmt, "WSStmtAddBatch");
IntPtr affectRowPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)));
LibTaosWS.WSStmtExecute(stmt, affectRowPtr);
ValidSTMTStep(code, stmt, "WSStmtExecute");
Console.WriteLine("STMT affect rows:{0}", Marshal.ReadInt32(affectRowPtr));
LibTaosWS.WSStmtClose(stmt);
// Free allocated memory
Marshal.FreeHGlobal(affectRowPtr);
WSMultiBind.WSFreeTaosBind(tags);
WSMultiBind.WSFreeTaosBind(data);
}
// close connect
LibTaosWS.WSClose(conn);
}
public static IntPtr Connect(string dsn)
{
// get connect
IntPtr conn = LibTaosWS.WSConnectWithDSN(dsn);
if (conn == IntPtr.Zero)
{
throw new Exception($"get connection failed,reason:{LibTaosWS.WSErrorStr(conn)},code:{LibTaosWS.WSErrorNo(conn)}");
}
return conn;
}
public static void ValidSTMTStep(int code, IntPtr wsStmt, string method)
{
if (code != 0)
{
throw new Exception($"{method} failed,reason: {LibTaosWS.WSErrorStr(wsStmt)}, code: {code}");
}
else
{
Console.WriteLine("{0} success", method);
}
}
}
}
Important Updates
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 | 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 client library for TDengine, supporting Linux and Windows platforms. Community contributor Maikebing@@maikebing contributes the library
. Please refer to:
- Interface download: https://github.com/maikebing/Maikebing.EntityFrameworkCore.Taos
Frequently Asked Questions
-
"Unable to establish connection", "Unable to resolve FQDN"
Usually, it's caused by an incorrect FQDN configuration. Please refer to this section in the FAQ to troubleshoot.
-
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 theC:\Windows\System32\
directory on Windows, and create the following soft link on Linuxln -s /usr/local/taos/driver/libtaos.so.x.x .x.x /usr/lib/libtaos.so
will work.