diff --git a/EFCore.Taos.sln b/EFCore.Taos.sln
index 7ea0fa5f97c3962d14079935f66ebfeeb4534ffc..425eb51514af0adfec62fb60536d83bdcf6be370 100644
--- a/EFCore.Taos.sln
+++ b/EFCore.Taos.sln
@@ -26,7 +26,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IoTSharp.HealthChecks.Taos"
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{1F3895A2-ED79-499F-A6A1-3F88A3D8D7F7}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFrameworkCore.Taos.Tests", "src\EntityFrameworkCore.Taos.Tests\EntityFrameworkCore.Taos.Tests.csproj", "{7F5F12D6-CA82-4499-AF3E-6CA7E61579CB}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFrameworkCore.Taos.Tests", "src\EntityFrameworkCore.Taos.Tests\EntityFrameworkCore.Taos.Tests.csproj", "{7F5F12D6-CA82-4499-AF3E-6CA7E61579CB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TaosOrm", "..\TaosOrm\TaosOrm.csproj", "{7F9F4104-3AFF-4D1E-8AD4-154957159ADC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -110,6 +112,18 @@ Global
{7F5F12D6-CA82-4499-AF3E-6CA7E61579CB}.Release|x64.Build.0 = Release|Any CPU
{7F5F12D6-CA82-4499-AF3E-6CA7E61579CB}.Release|x86.ActiveCfg = Release|Any CPU
{7F5F12D6-CA82-4499-AF3E-6CA7E61579CB}.Release|x86.Build.0 = Release|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Debug|x64.Build.0 = Debug|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Debug|x86.Build.0 = Debug|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Release|x64.ActiveCfg = Release|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Release|x64.Build.0 = Release|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Release|x86.ActiveCfg = Release|Any CPU
+ {7F9F4104-3AFF-4D1E-8AD4-154957159ADC}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/TaosOrm/Program.cs b/TaosOrm/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c9a9a0f2d728dfade5e25ea49daa1bf6db7b2314
--- /dev/null
+++ b/TaosOrm/Program.cs
@@ -0,0 +1,23 @@
+using System;
+using TaosOrm.Test;
+
+namespace TaosOrm
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ TaosSugar taosSugar = new TaosSugar();
+ taosSugar.TaosAddAsync(
+ new EntityDemo()
+ {
+ Current = 2,
+ Phase = 30,
+ Voltage = 4,
+ EquipId = "3afbe36dd5b740a6b7c1634b70687d51",
+ GroupId = 1
+ }, true);
+ Console.WriteLine("Hello World!");
+ }
+ }
+}
diff --git a/TaosOrm/TaosAttribute.cs b/TaosOrm/TaosAttribute.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7a88390536cf23948be9073cddf77e4bee21cdc4
--- /dev/null
+++ b/TaosOrm/TaosAttribute.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TaosOrm
+{
+ [Serializable]
+ public class TaosAttribute : Attribute
+ {
+
+ ///
+ /// 超级表
+ ///
+ public string SuperTableName { get; }
+ ///
+ /// 构造函数
+ ///
+ /// 超级表名
+ public TaosAttribute(string superTableName)
+ {
+ SuperTableName = superTableName;
+ }
+ }
+ [Serializable]
+ public class TaosColumnAttribute : Attribute
+ {
+ ///
+ /// 列名字
+ ///
+ public string ColumnName { get; set; }
+ ///
+ /// 列类型
+ ///
+ public TaosDataType ColumnType { get; set; }
+ public string ColumnLength { get; set; }
+ ///
+ /// 是否标签
+ ///
+ public bool IsTag { get; set; } = false;
+ ///
+ /// 是否为表名
+ ///
+ public bool IsTableName { get; set; }
+ public TaosColumnAttribute(string columnName, TaosDataType columnType, string columnLength = null, bool isTag = false, bool isTableName = false)
+ {
+ ColumnName = columnName;
+ ColumnType = columnType;
+ ColumnLength = columnLength;
+ IsTag = isTag;
+ IsTableName = isTableName;
+ }
+ }
+}
diff --git a/TaosOrm/TaosDataType.cs b/TaosOrm/TaosDataType.cs
new file mode 100644
index 0000000000000000000000000000000000000000..659b50732ce9635cbf86a62495ebcf164fe4acb3
--- /dev/null
+++ b/TaosOrm/TaosDataType.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TaosOrm
+{
+ ///
+ /// 涛思时序数据库10种数据类型
+ /// https://www.bookstack.cn/read/TDengin-2.0-zh/spilt.1.33f53af4c5509954.md
+ ///
+ public enum TaosDataType
+ {
+ TIMESTAMP,
+ INT,
+ BIGINT,
+ FLOAT,
+ DOUBLE,
+ BINARY,
+ SMALLINT,
+ TINYINT,
+ BOOL,
+ NCHAR
+ }
+}
diff --git a/TaosOrm/TaosOrm.csproj b/TaosOrm/TaosOrm.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..a5c3b75e96a6cbf78c51b1672e54ddef616961f3
--- /dev/null
+++ b/TaosOrm/TaosOrm.csproj
@@ -0,0 +1,12 @@
+
+
+
+ Exe
+ net5.0
+
+
+
+
+
+
+
diff --git a/TaosOrm/TaosSugar.cs b/TaosOrm/TaosSugar.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ea004da56f056f67dc800e96c9365d64a39578f9
--- /dev/null
+++ b/TaosOrm/TaosSugar.cs
@@ -0,0 +1,204 @@
+using IoTSharp.Data.Taos;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TaosOrm
+{
+ ///
+ /// 时序数据库Orm 查询未实现
+ ///
+ public class TaosSugar
+ {
+ private readonly TaosConnection _taos;
+ private static readonly ConcurrentDictionary _tableStructure = new();// 表名缓存
+ public TaosSugar()
+ {
+ _taos = new TaosConnection("连接地址");
+ if (_taos.State != System.Data.ConnectionState.Open) _taos.Open();
+ }
+ ///
+ /// 数据新增
+ ///
+ /// 实体对象
+ ///
+ /// 为True 检查超级表结构是否存在不存在就创建
+ ///
+ public async Task TaosAddAsync(TEntity entity, bool checkDB = false) where TEntity : class
+ {
+ //获取超级表结构
+ var st = GetSuperTaosStructure(entity);
+ //获取值列表
+ StringBuilder tagValue = new StringBuilder();
+ StringBuilder columnValue = new StringBuilder();
+ PropertyInfo[] infos = entity.GetType().GetProperties();
+ if (checkDB) CheckDataBase(st, infos);//监测表结构是否存在
+ TaosColumnAttribute dfAttr = null;
+ object[] dfAttrs;
+ int tags = 0;
+ int columns = 0;
+ foreach (PropertyInfo info in infos)
+ {
+ dfAttrs = info.GetCustomAttributes(typeof(TaosColumnAttribute), false);
+ if (dfAttrs.Length > 0)
+ {
+ dfAttr = dfAttrs[0] as TaosColumnAttribute;
+ if (dfAttr is TaosColumnAttribute)
+ {
+ if (dfAttr.IsTag)
+ {
+ if (dfAttr.IsTableName)//是不是为表名的字段
+ {
+ st.TableName = info.GetValue(entity, null).ToString();
+ }
+ //tagName.Append(tags > 0 ? "," + dfAttr.ColumnName : dfAttr.ColumnName);
+ if (dfAttr.ColumnType == TaosDataType.BINARY || dfAttr.ColumnType == TaosDataType.NCHAR)//字符串就得加''
+ {
+ tagValue.Append(tags > 0 ? "," + $"'{info.GetValue(entity, null)}'" : $"'{info.GetValue(entity, null)}'");
+ }
+ else
+ {
+ tagValue.Append(tags > 0 ? "," + info.GetValue(entity, null) : info.GetValue(entity, null));
+ }
+ tags++;
+ }
+ else
+ {
+ //columnName.Append(columns > 0 ? "," + dfAttr.ColumnName : dfAttr.ColumnName);
+ if (dfAttr.ColumnType == TaosDataType.BINARY || dfAttr.ColumnType == TaosDataType.NCHAR)//字符串就得加''
+ {
+ columnValue.Append(columns > 0 ? "," + $"'{info.GetValue(entity, null)}'" : $"'{info.GetValue(entity, null)}'");
+ }
+ else
+ {
+ columnValue.Append(columns > 0 ? "," + info.GetValue(entity, null) : info.GetValue(entity, null));
+ }
+ columns++;
+ }
+ }
+ }
+ }
+ if (st.TableName == null) throw new Exception("未设备表名特性");
+ string strInsertSQL = @$"INSERT INTO D_{st.TableName} USING
+ {st.SuperTableName}
+ ({string.Join(",", st.TagNames)}) TAGS({tagValue})
+ (ts,{string.Join(",", st.ColumnNames)}) VALUES(now,{columnValue})";
+#if DEBUG
+ Console.WriteLine($"TaosSql:{strInsertSQL}");
+#endif
+ return await _taos.CreateCommand(strInsertSQL).ExecuteNonQueryAsync();
+ }
+ ///
+ /// 缓存超级表结构
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static TaosStructure GetSuperTaosStructure(TEntity entity) where TEntity : class
+ {
+ Type entityType = entity.GetType();
+ PropertyInfo[] infos = entityType.GetProperties();
+ TaosStructure dt = _tableStructure.ContainsKey(entityType.FullName) ? _tableStructure[entityType.FullName] : null;
+ if (dt == null)
+ {
+ TaosStructure taos = new TaosStructure();
+ TaosColumnAttribute dfAttr = null;
+ object[] dfAttrs;
+ if (entityType.GetCustomAttributes(typeof(TaosAttribute), false)[0] is TaosAttribute dtAttr)
+ {
+ taos.SuperTableName = dtAttr.SuperTableName;
+ }
+ else
+ {
+ throw new Exception(entityType.ToString() + "未设置DataTable特性。");
+ }
+ foreach (PropertyInfo info in infos)
+ {
+ dfAttrs = info.GetCustomAttributes(typeof(TaosColumnAttribute), false);
+ if (dfAttrs.Length > 0)
+ {
+ dfAttr = dfAttrs[0] as TaosColumnAttribute;
+ if (dfAttr is TaosColumnAttribute)
+ {
+ if (dfAttr.IsTag)
+ {
+ taos.TagNames.Add(dfAttr.ColumnName);
+ }
+ else
+ {
+ taos.ColumnNames.Add(dfAttr.ColumnName);
+ }
+ }
+ }
+ }
+ _tableStructure[entityType.FullName] = taos;
+ return taos;
+ }
+ return dt;
+ }
+ ///
+ /// 创建DB与超级表
+ ///
+ ///
+ ///
+ private void CheckDataBase(TaosStructure st, PropertyInfo[] infos)
+ {
+ //backlog:切换DB不能实现 有BUG
+ _taos.CreateCommand($"CREATE DATABASE IF NOT EXISTS {_taos.Database} KEEP 365 DAYS 10 BLOCKS 4;").ExecuteNonQuery();
+ _taos.ChangeDatabase(_taos.Database);//创建后切换DB
+ StringBuilder columnTag = new StringBuilder();
+ StringBuilder column = new StringBuilder();
+ TaosColumnAttribute dfAttr = null;
+ object[] dfAttrs;
+ int tags = 0;
+ int columns = 0;
+ foreach (PropertyInfo info in infos)
+ {
+ dfAttrs = info.GetCustomAttributes(typeof(TaosColumnAttribute), false);
+ if (dfAttrs.Length > 0)
+ {
+ dfAttr = dfAttrs[0] as TaosColumnAttribute;
+ if (dfAttr is TaosColumnAttribute)
+ {
+ string length = "";
+ if (dfAttr.ColumnLength != null)
+ {
+ length = $"({dfAttr.ColumnLength})";//判断数据类型是否有长度有些没有长度
+ }
+ if (dfAttr.IsTag)//是标签
+ {
+ string tag = $"{dfAttr.ColumnName} {dfAttr.ColumnType}{length}";
+ columnTag.Append(tags > 0 ? "," + tag : tag);
+ tags++;
+ }
+ else
+ {
+ string tag = $"{dfAttr.ColumnName} {dfAttr.ColumnType}{length}";
+ column.Append(columns > 0 ? "," + tag : tag);
+ columns++;
+ }
+ }
+ }
+ }
+ //创建超级表
+ _taos.CreateCommand($@"CREATE TABLE IF NOT EXISTS {_taos.Database}.{st.SuperTableName}
+ (`ts` TIMESTAMP,
+ {column}) TAGS ({columnTag});")
+ .ExecuteNonQuery();
+ }
+
+
+ }
+ public class TaosStructure
+ {
+ public string TableName { get; set; }//表名是动态值 (为设备ID)
+ public string SuperTableName { get; set; }
+ public List TagNames { get; set; } = new List();
+ public List ColumnNames { get; set; } = new List();
+ }
+}
diff --git a/TaosOrm/Test/EntityDemo.cs b/TaosOrm/Test/EntityDemo.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8c9eef6683e38b0bb5cd5aaccf7fd2a910c5536e
--- /dev/null
+++ b/TaosOrm/Test/EntityDemo.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TaosOrm.Test
+{
+ [Taos("BREAKER_BASIC")]//超级表名
+ [Description("时序表")]
+ public class EntityDemo
+ {
+ ///
+ /// 特性含义:别名,类型,类型长度,是否为Tag,是否为表名[表名只能设置一个字段]
+ ///
+ [TaosColumn("equipId", TaosDataType.BINARY, "64", true, true)]
+ public string EquipId { get; set; }
+
+ [TaosColumn("groupid", TaosDataType.INT, isTag: true)]
+ public int GroupId { get; set; }
+
+ [TaosColumn("current", TaosDataType.FLOAT)]
+ public double Current { get; set; }
+
+ [TaosColumn("voltage", TaosDataType.INT)]
+ public int Voltage { get; set; }
+
+ [TaosColumn("phase", TaosDataType.FLOAT)]
+ public double Phase { get; set; }
+ }
+}