解决单侧点表模型路径处理问题,并添加路径Attribute,以支持固定存储路径场景

This commit is contained in:
ChenYi 2025-04-21 14:57:12 +08:00
parent ca1a23fd33
commit 309f5c37d2
8 changed files with 132 additions and 15 deletions

View File

@ -1,7 +1,7 @@
namespace JiShe.CollectBus.IoTDB.Attribute namespace JiShe.CollectBus.IoTDB.Attribute
{ {
/// <summary> /// <summary>
/// 用于标识当前实体为单侧点模式单侧点模式只有一个Filed标识字段,类型是Tuple<string,object>,Item1=>测点名称Item2=>测点值,泛型 /// 用于标识当前实体为单侧点模式单侧点模式只有一个Filed标识字段,类型是Tuple<string,T>,Item1=>测点名称Item2=>测点值,泛型
/// </summary> /// </summary>
[AttributeUsage(AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Property)]
public class SingleMeasuringAttribute : System.Attribute public class SingleMeasuringAttribute : System.Attribute

View File

@ -0,0 +1,18 @@
using JiShe.CollectBus.IoTDB.Enums;
namespace JiShe.CollectBus.IoTDB.Attribute
{
/// <summary>
/// IoTDB实体存储路径或表名称一般用于已经明确的存储路径或表名称例如日志存储
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class TableNameOrTreePathAttribute : System.Attribute
{
public string TableNameOrTreePath { get; }
public TableNameOrTreePathAttribute(string tableNameOrTreePath)
{
TableNameOrTreePath = tableNameOrTreePath;
}
}
}

View File

@ -3,7 +3,7 @@
namespace JiShe.CollectBus.IoTDB.Model namespace JiShe.CollectBus.IoTDB.Model
{ {
/// <summary> /// <summary>
/// IoT实体基类此类适用于多个数据测点记录场景单个测点请使用子类 SingleMeasuringEntity /// IoT实体基类此类适用于多个数据测点记录场景单个测点请使用子类 SingleMeasuring
/// </summary> /// </summary>
public abstract class IoTEntity public abstract class IoTEntity
{ {

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JiShe.CollectBus.IoTDB.Attribute;
using JiShe.CollectBus.IoTDB.Enums;
using JiShe.CollectBus.IoTDB.Provider;
namespace JiShe.CollectBus.IoTDB.Model
{
/// <summary>
/// Table模型单项数据实体
/// </summary>
[EntityType(EntityTypeEnum.TableModel)]
public class TableModelSingleMeasuringEntity<T> : IoTEntity
{
/// <summary>
/// 单项数据键值对
/// </summary>
[SingleMeasuring(nameof(SingleColumn))]
public required Tuple<string, T> SingleColumn { get; set; }
}
}

View File

@ -10,13 +10,13 @@ using JiShe.CollectBus.IoTDB.Provider;
namespace JiShe.CollectBus.IoTDB.Model namespace JiShe.CollectBus.IoTDB.Model
{ {
/// <summary> /// <summary>
/// 单项数据实体 /// Tree模型单项数据实体
/// </summary> /// </summary>
[EntityType(EntityTypeEnum.TreeModel)] [EntityType(EntityTypeEnum.TreeModel)]
public class SingleMeasuringEntity<T> : IoTEntity public class TreeModelSingleMeasuringEntity<T> : IoTEntity
{ {
/// <summary> /// <summary>
/// 单项数据 /// 单项数据键值
/// </summary> /// </summary>
[SingleMeasuring(nameof(SingleMeasuring))] [SingleMeasuring(nameof(SingleMeasuring))]
public required Tuple<string, T> SingleMeasuring { get; set; } public required Tuple<string, T> SingleMeasuring { get; set; }

View File

@ -30,6 +30,17 @@ namespace JiShe.CollectBus.IoTDB.Provider
var type = typeof(T); var type = typeof(T);
return $"{type.Name.ToLower()}"; return $"{type.Name.ToLower()}";
} }
/// <summary>
/// 获取表名称,用作单侧点表模型特殊处理。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
public static string GetDeviceTableName<T>(T entity) where T : IoTEntity
{
return $"{entity.SystemName.ToLower()}.`{entity.ProjectCode}`.`{entity.DeviceType}`.`{entity.DeviceId}`";
}
} }
} }

View File

@ -159,6 +159,12 @@ namespace JiShe.CollectBus.IoTDB.Provider
throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 table模型不能使用tree模型Session连接属于异常情况-104"); throw new ArgumentException($"{nameof(BuildTablet)} 构建存储结构{nameof(Tablet)}时 table模型不能使用tree模型Session连接属于异常情况-104");
} }
string tableNameOrTreePath = string.Empty;
var tableNameOrTreePathAttribute = typeof(T).GetCustomAttribute<TableNameOrTreePathAttribute>();
if (tableNameOrTreePathAttribute != null)
{
tableNameOrTreePath = tableNameOrTreePathAttribute.TableNameOrTreePath;
}
foreach (var entity in entities) foreach (var entity in entities)
{ {
@ -198,6 +204,12 @@ namespace JiShe.CollectBus.IoTDB.Provider
{ {
rowValues.Add(null); rowValues.Add(null);
} }
//同时如果是单测点模式且是table模型存储路径只能通过DevicePathBuilder.GetDeviceTableName(entity)获取
if (_runtimeContext.UseTableSessionPool)
{
tableNameOrTreePath = DevicePathBuilder.GetDeviceTableName(entity);
}
} }
else else
{ {
@ -209,6 +221,13 @@ namespace JiShe.CollectBus.IoTDB.Provider
values.Add(rowValues); values.Add(rowValues);
//如果指定了路径
if (!string.IsNullOrWhiteSpace(tableNameOrTreePath))
{
devicePaths.Add(tableNameOrTreePath);
}
else
{
if (!_runtimeContext.UseTableSessionPool)//树模型 if (!_runtimeContext.UseTableSessionPool)//树模型
{ {
devicePaths.Add(DevicePathBuilder.GetDevicePath(entity)); devicePaths.Add(DevicePathBuilder.GetDevicePath(entity));
@ -219,6 +238,8 @@ namespace JiShe.CollectBus.IoTDB.Provider
} }
} }
}
if (devicePaths.Count > 1) if (devicePaths.Count > 1)
{ {
throw new Exception($"{nameof(BuildTablet)} 构建Tablet《{typeof(T).Name}》时,批量插入的设备路径不一致。"); throw new Exception($"{nameof(BuildTablet)} 构建Tablet《{typeof(T).Name}》时,批量插入的设备路径不一致。");

View File

@ -9,6 +9,7 @@ using JiShe.CollectBus.IoTDB.Context;
using JiShe.CollectBus.IoTDB.Interface; using JiShe.CollectBus.IoTDB.Interface;
using JiShe.CollectBus.IoTDB.Model; using JiShe.CollectBus.IoTDB.Model;
using JiShe.CollectBus.IoTDB.Options; using JiShe.CollectBus.IoTDB.Options;
using JiShe.CollectBus.IoTDB.Provider;
using JiShe.CollectBus.IotSystems.PrepayModel; using JiShe.CollectBus.IotSystems.PrepayModel;
using JiShe.CollectBus.Kafka.Attributes; using JiShe.CollectBus.Kafka.Attributes;
using JiShe.CollectBus.Kafka.Internal; using JiShe.CollectBus.Kafka.Internal;
@ -150,14 +151,14 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
} }
/// <summary> /// <summary>
/// 测试单个测点数据项 /// 测试树模型单个测点数据项
/// </summary> /// </summary>
/// <param name="measuring"></param> /// <param name="measuring"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
public async Task TestSingleMeasuringAFNData(string measuring, string value, DateTime time) public async Task TestTreeModelSingleMeasuringEntity(string measuring, string value, DateTime time)
{ {
var meter = new SingleMeasuringEntity<string>() var meter = new TreeModelSingleMeasuringEntity<string>()
{ {
SystemName = "energy", SystemName = "energy",
DeviceId = "402440506", DeviceId = "402440506",
@ -170,14 +171,14 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
} }
/// <summary> /// <summary>
/// 测试单个测点数据项2 /// 测试树模型单个测点数据项2
/// </summary> /// </summary>
/// <param name="measuring"></param> /// <param name="measuring"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
public async Task TestSingleMeasuringAFNData2(string measuring, int value, DateTime time) public async Task TestTreeModelSingleMeasuringEntity2(string measuring, int value, DateTime time)
{ {
var meter = new SingleMeasuringEntity<int>() var meter = new TreeModelSingleMeasuringEntity<int>()
{ {
SystemName = "energy", SystemName = "energy",
DeviceId = "402440506", DeviceId = "402440506",
@ -189,6 +190,48 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
await _iotDBProvider.InsertAsync(meter); await _iotDBProvider.InsertAsync(meter);
} }
/// <summary>
/// 测试表模型单个测点数据项
/// </summary>
/// <param name="measuring"></param>
/// <returns></returns>
[HttpGet]
public async Task TestTableModelSingleMeasuringEntity(string measuring, string value, DateTime time)
{
var meter = new TableModelSingleMeasuringEntity<string>()
{
SystemName = "energy",
DeviceId = "402440506",
DeviceType = "Ammeter",
ProjectCode = "10059",
Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(),
SingleColumn = new Tuple<string, string>(measuring, value)
};
_dbContext.UseTableSessionPool = true;
await _iotDBProvider.InsertAsync(meter);
}
/// <summary>
/// 测试表模型单个测点数据项2
/// </summary>
/// <param name="measuring"></param>
/// <returns></returns>
[HttpGet]
public async Task TestTableModelSingleMeasuringEntity2(string measuring, int value, DateTime time)
{
var meter = new TableModelSingleMeasuringEntity<int>()
{
SystemName = "energy",
DeviceId = "402440506",
DeviceType = "Ammeter",
ProjectCode = "10059",
Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(),
SingleColumn = new Tuple<string, int>(measuring, value)
};
_dbContext.UseTableSessionPool = true;
await _iotDBProvider.InsertAsync(meter);
}
/// <summary> /// <summary>
/// 测试设备分组均衡控制算法 /// 测试设备分组均衡控制算法
/// </summary> /// </summary>