From 53e6bb252ab74375010fbe6877ce5ced5590e47d Mon Sep 17 00:00:00 2001
From: ChenYi <296215406@outlook.com>
Date: Tue, 6 May 2025 23:46:12 +0800
Subject: [PATCH 1/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D15=E5=88=86=E9=92=9F?=
=?UTF-8?q?=E4=BB=BB=E5=8A=A1Kafka=E4=B8=BB=E9=A2=98=E5=BC=82=E5=B8=B8?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E6=96=B0=E5=A2=9E=E5=A2=9E?=
=?UTF-8?q?=E9=87=8F=E6=BA=90=E7=A0=81=E5=B7=A5=E5=8E=82=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ComplexTypeSourceAnalyzers.cs | 217 ++++++++++++++----
.../Samples/SampleAppService.cs | 5 +
.../BasicScheduledMeterReadingService.cs | 2 +-
...rsProvider.cs => ISourceEntityAccessor.cs} | 4 +-
4 files changed, 178 insertions(+), 50 deletions(-)
rename shared/JiShe.CollectBus.Analyzers.Shared/{ISourceAnalyzersProvider.cs => ISourceEntityAccessor.cs} (92%)
diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
index 20951e5..8ec5eb9 100644
--- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
+++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
@@ -14,17 +14,14 @@ namespace JiShe.CollectBus.IncrementalGenerator
public class ComplexTypeSourceAnalyzers : IIncrementalGenerator
{
private const string AttributeFullName = "JiShe.CollectBus.Analyzers.Shared.SourceAnalyzersAttribute";
+ private const string SourceEntityAccessorFactoryNamespace = "JiShe.CollectBus.Analyzers.Shared";
public void Initialize(IncrementalGeneratorInitializationContext context)
{
//Debugger.Launch();
- context.RegisterPostInitializationOutput(ctx =>
- {
- ctx.AddSource("GeneratorInit.g.cs", "// Initialization Marker");
- });
- // 步骤1:筛选带有 [GenerateAccessors] 的类
+ // 步骤1:筛选带有 [SourceAnalyzers] 的类
var classDeclarations = context.SyntaxProvider
.CreateSyntaxProvider(
predicate: static (s, _) => IsClassWithAttribute(s),
@@ -35,12 +32,11 @@ namespace JiShe.CollectBus.IncrementalGenerator
var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect());
context.RegisterSourceOutput(compilationAndClasses, (spc, source) =>
- GenerateCode(source.Left, source.Right!, spc));
+ GenerateCode(source.Left, source.Right!, spc));
}
private static bool IsClassWithAttribute(SyntaxNode node) => node is ClassDeclarationSyntax cds && cds.AttributeLists.Count > 0;
-
private static ClassDeclarationSyntax GetClassDeclaration(GeneratorSyntaxContext context)
{
var classDecl = (ClassDeclarationSyntax)context.Node;
@@ -76,18 +72,24 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
}
+ ///
+ /// 生成代码
+ ///
+ ///
+ ///
+ ///
private static void GenerateCode(
Compilation compilation,
IEnumerable classes,
SourceProductionContext context)
{
var processedTypes = new HashSet(SymbolEqualityComparer.Default);
-
+
if (!classes.Any())
{
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor("GEN002", "No Targets",
- "No classes with [GenerateAccessors] found", "Debug", DiagnosticSeverity.Warning, true),
+ new DiagnosticDescriptor("GEN002", "没有目标类",
+ "没有找到SourceAnalyzers标记的类", "Debug", DiagnosticSeverity.Warning, true),
Location.None));
}
@@ -99,46 +101,66 @@ namespace JiShe.CollectBus.IncrementalGenerator
if (classSymbol == null || !processedTypes.Add(classSymbol))
{
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor("GEN003", "Invalid Symbol",
- $"Class symbol is null for {classDecl.Identifier.Text}", "Error", DiagnosticSeverity.Error, true),
+ new DiagnosticDescriptor("GEN003", "无效符号",
+ $"类名称为{classDecl.Identifier.Text} 符号为空", "Error", DiagnosticSeverity.Error, true),
Location.None));
continue;
}
- context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(
- "PA001",
- "Generated Accessors",
- $"Generating accessors for {classSymbol.Name}",
- "Performance",
- DiagnosticSeverity.Info,
- true),
- Location.None));
+ //context.ReportDiagnostic(Diagnostic.Create(
+ //new DiagnosticDescriptor(
+ // "PA001",
+ // "Generated Accessors",
+ // $"Generating accessors for {classSymbol.Name}",
+ // "Performance",
+ // DiagnosticSeverity.Info,
+ // true),
+ //Location.None));
- // 新增:输出继承链信息
- context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor("HIERARCHY", "Class Hierarchy",
- $"Processing class: {classSymbol.Name}, BaseType: {classSymbol.BaseType?.Name}",
- "Debug", DiagnosticSeverity.Info, true),
- Location.None));
+ //// 新增:输出继承链信息
+ //context.ReportDiagnostic(Diagnostic.Create(
+ // new DiagnosticDescriptor("HIERARCHY", "Class Hierarchy",
+ // $"Processing class: {classSymbol.Name}, BaseType: {classSymbol.BaseType?.Name}",
+ // "Debug", DiagnosticSeverity.Info, true),
+ // Location.None));
- context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor("PA002", "Class Found",
- $"Processing class: {classSymbol.Name}", "Debug", DiagnosticSeverity.Warning, true),
- Location.None));
+ //context.ReportDiagnostic(Diagnostic.Create(
+ //new DiagnosticDescriptor("PA002", "Class Found",
+ //$"Processing class: {classSymbol.Name}", "Debug", DiagnosticSeverity.Warning, true),
+ //Location.None));
var code = BuildAccessorsForType(classSymbol, compilation, processedTypes);
- System.Diagnostics.Debug.WriteLine($"Generated code for {classSymbol.Name}:\n{code}"); // 调试输出
+ //System.Diagnostics.Debug.WriteLine($"Generated code for {classSymbol.Name}:\n{code}"); // 调试输出
context.AddSource($"{classSymbol.Name}Extension.g.cs", code);
+
+
+ var code3 = BuildAccessorsForType2(classSymbol, compilation, processedTypes);
+ context.AddSource($"{classSymbol.Name}Accessor.g.cs", code3);
+
+ //code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
+ //if (classSymbol.ContainingNamespace.ToDisplayString() == "JiShe.CollectBus.IoTDB")
+ //{
+
+ //}
}
+
+ // 生成工厂注册代码
+ context.AddSource("SourceEntityAccessorFactory.g.cs", BuildFactoryCode());
}
+ ///
+ /// 构建类的属性访问器代码
+ ///
+ ///
+ ///
+ ///
+ ///
private static string BuildAccessorsForType(
- INamedTypeSymbol classSymbol,
- Compilation compilation,
- HashSet processedTypes)
+ INamedTypeSymbol classSymbol,
+ Compilation compilation,
+ HashSet processedTypes)
{
var code = new StringBuilder();
code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
@@ -151,25 +173,67 @@ namespace JiShe.CollectBus.IncrementalGenerator
code.AppendLine($"public static class {classSymbol.Name}Extension{GetGenericParams(classSymbol)}");
code.AppendLine("{");
- //foreach (var prop in classSymbol.GetMembers().OfType())
- //{
- // if (prop.IsIndexer) continue;
-
- // GeneratePropertyAccessors(prop, code, compilation, processedTypes);
- //}
-
foreach (var prop in GetAllPropertiesInHierarchy(classSymbol))
{
if (prop.IsIndexer) continue;
- GeneratePropertyAccessors(prop, code, compilation, processedTypes);
+ GeneratePropertyAccessorsForType(prop, code, compilation, processedTypes);
}
code.AppendLine("}");
return code.ToString();
}
- //private static string GetGenericParams(INamedTypeSymbol symbol)
- // => symbol.IsGenericType ? $"<{string.Join(", ", symbol.TypeParameters.Select(t => t.Name))}>" : "";
+ ///
+ /// 构建类的属性访问器代码
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static string BuildAccessorsForType2(
+ INamedTypeSymbol classSymbol,
+ Compilation compilation,
+ HashSet processedTypes)
+ {
+ var code = new StringBuilder();
+ code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
+ code.AppendLine("// Generated code for " + classSymbol.Name);
+ code.AppendLine("// ");
+ code.AppendLine("#nullable enable");
+ code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
+ code.AppendLine();
+
+ code.AppendLine($"public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>");
+ code.AppendLine("{");
+
+ foreach (var prop in GetAllPropertiesInHierarchy(classSymbol))
+ {
+ if (prop.IsIndexer) continue;
+ GeneratePropertyAccessorsForType(prop, code, compilation, processedTypes);
+ }
+
+ code.AppendLine("}");
+
+ //var code3 = $@"
+ // public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>
+ // {{
+ // public object GetPropertyValue({classSymbol.Name} entity, string propName) => propName switch
+ // {{
+ // {GeneratePropertyCases(classSymbol)}
+ // _ => throw new ArgumentException(""无效属性名"")
+ // }};
+
+ // {GenerateTupleSupport(classSymbol)}
+ // }}";
+
+ return code.ToString();
+ }
+
+ ///
+ /// 获取泛型参数
+ ///
+ ///
+ ///
public static string GetGenericParams(INamedTypeSymbol symbol)
{
if (!symbol.IsGenericType) return "";
@@ -177,13 +241,20 @@ namespace JiShe.CollectBus.IncrementalGenerator
return $"<{string.Join(", ", parameters)}>";
}
- private static void GeneratePropertyAccessors(
+ ///
+ /// 生成属性访问器代码
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void GeneratePropertyAccessorsForType(
IPropertySymbol prop,
StringBuilder code,
Compilation compilation,
HashSet processedTypes)
{
- // 关键修复点1:安全类型转换
+ // 安全类型转换
if (prop.Type is not ITypeSymbol propType) return;
code.AppendLine($" // Processing property: {prop.Name}");
@@ -200,6 +271,12 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
}
+ ///
+ /// 处理元组类型
+ ///
+ ///
+ ///
+ ///
private static void GenerateTupleAccessors(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
{
var elements = tupleType.TupleElements;
@@ -222,6 +299,12 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
}
+ ///
+ /// 生成标准属性的访问器
+ ///
+ ///
+ ///
+ ///
private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
{
var parentType = prop.ContainingType.ToDisplayString();
@@ -233,6 +316,13 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
}
+
+ ///
+ /// 处理嵌套类型
+ ///
+ ///
+ ///
+ ///
private static void ProcessNestedType(ITypeSymbol typeSymbol, Compilation compilation, HashSet processedTypes)
{
if (typeSymbol is not INamedTypeSymbol namedType) return;
@@ -242,6 +332,11 @@ namespace JiShe.CollectBus.IncrementalGenerator
var code = BuildAccessorsForType(namedType, compilation, processedTypes);
}
+ ///
+ /// 处理嵌套类型
+ ///
+ ///
+ ///
private static bool ShouldProcessNestedType(INamedTypeSymbol symbol)
{
return symbol.DeclaredAccessibility == Accessibility.Public &&
@@ -250,5 +345,33 @@ namespace JiShe.CollectBus.IncrementalGenerator
!symbol.IsImplicitlyDeclared &&
!symbol.Name.StartsWith("<");
}
+
+ ///
+ /// 生成扩展类工厂代码
+ ///
+ ///
+ private static string BuildFactoryCode()
+ {
+ return """
+ using System;
+ using System.Collections.Concurrent;
+ namespace JiShe.CollectBus.Analyzers.Shared;
+ public static class SourceEntityAccessorFactory
+ {
+ private static readonly ConcurrentDictionary _accessors = new();
+
+ public static ISourceEntityAccessor GetAccessor()
+ {
+ if (!_accessors.TryGetValue(typeof(T), out var accessor))
+ {
+ accessor = Activator.CreateInstance(
+ Type.GetType($"{typeof(T).Namespace}.{typeof(T).Name}Accessor")!)!;
+ _accessors.TryAdd(typeof(T), accessor);
+ }
+ return (ISourceEntityAccessor)accessor!;
+ }
+ }
+ """;
+ }
}
}
\ No newline at end of file
diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
index ea2415e..79f0244 100644
--- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
+++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
@@ -53,6 +53,10 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
[HttpGet]
public async Task UseSessionPool(long testTime)
{
+ var dataTime = DateTime.Now;
+
+ List values = new List() { $"{dataTime:yy}", $"{dataTime:MM}", $"{dataTime:dd}", $"{dataTime:HH}", $"{dataTime:mm}", };
+
ElectricityMeterTreeModel meter = new ElectricityMeterTreeModel()
{
@@ -67,6 +71,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
Timestamps = testTime// DateTimeOffset.UtcNow.ToUnixTimeNanoseconds()//testTime.GetDateTimeOffset().ToUnixTimeNanoseconds(),
};
//ElectricityMeterTreeModelExtension.GetCurrent()
+ //SourceEntityAccessorFactory.SetCurrent(meter);
await _iotDBProvider.InsertAsync(meter);
}
diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
index 2104d28..47b8a99 100644
--- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
+++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
@@ -262,7 +262,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
//_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
return;
}
- _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, Tuple.Create(ProtocolConst.AmmeterSubscriberWorkerAutoValveControlIssuedEventName, tempTask));
+ _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, Tuple.Create(ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempTask));
});
}
else if (meteryType == MeterTypeEnum.WaterMeter.ToString())
diff --git a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceAnalyzersProvider.cs b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
similarity index 92%
rename from shared/JiShe.CollectBus.Analyzers.Shared/ISourceAnalyzersProvider.cs
rename to shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
index 905f0ef..3395239 100644
--- a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceAnalyzersProvider.cs
+++ b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
@@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.Text;
-namespace JiShe.CollectBus.Analyzers
+namespace JiShe.CollectBus.Analyzers.Shared
{
- public interface ISourceAnalyzersProvider
+ public interface ISourceEntityAccessor
{
///
/// 获取属性值
From bca72025586daaab407c258c6c240183f17cb031 Mon Sep 17 00:00:00 2001
From: ChenYi <296215406@outlook.com>
Date: Wed, 7 May 2025 10:15:45 +0800
Subject: [PATCH 2/6] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=A4=8D=E6=9D=82?=
=?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=A2=9E=E9=87=8F=E6=BA=90=E7=94=9F=E6=88=90?=
=?UTF-8?q?=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ComplexTypeSourceAnalyzers.cs | 247 ++++++++++++------
.../Model/TableModelSingleMeasuringEntity.cs | 2 +-
.../Model/TreeModelSingleMeasuringEntity.cs | 2 +-
.../Samples/SampleAppService.cs | 2 +
.../ISourceEntityAccessor.cs | 26 +-
5 files changed, 177 insertions(+), 102 deletions(-)
diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
index 8ec5eb9..3b25aa0 100644
--- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
+++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
@@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@@ -8,7 +9,7 @@ using System.Text;
namespace JiShe.CollectBus.IncrementalGenerator
{
///
- /// 复杂类型源生成器
+ /// 复杂类型增量源生成器
///
[Generator(LanguageNames.CSharp)]
public class ComplexTypeSourceAnalyzers : IIncrementalGenerator
@@ -32,11 +33,11 @@ namespace JiShe.CollectBus.IncrementalGenerator
var compilationAndClasses = context.CompilationProvider.Combine(classDeclarations.Collect());
context.RegisterSourceOutput(compilationAndClasses, (spc, source) =>
- GenerateCode(source.Left, source.Right!, spc));
+ GenerateCode(source.Left, source.Right!, spc));
}
private static bool IsClassWithAttribute(SyntaxNode node) => node is ClassDeclarationSyntax cds && cds.AttributeLists.Count > 0;
-
+
private static ClassDeclarationSyntax GetClassDeclaration(GeneratorSyntaxContext context)
{
var classDecl = (ClassDeclarationSyntax)context.Node;
@@ -106,44 +107,14 @@ namespace JiShe.CollectBus.IncrementalGenerator
Location.None));
continue;
}
-
- //context.ReportDiagnostic(Diagnostic.Create(
- //new DiagnosticDescriptor(
- // "PA001",
- // "Generated Accessors",
- // $"Generating accessors for {classSymbol.Name}",
- // "Performance",
- // DiagnosticSeverity.Info,
- // true),
- //Location.None));
-
- //// 新增:输出继承链信息
- //context.ReportDiagnostic(Diagnostic.Create(
- // new DiagnosticDescriptor("HIERARCHY", "Class Hierarchy",
- // $"Processing class: {classSymbol.Name}, BaseType: {classSymbol.BaseType?.Name}",
- // "Debug", DiagnosticSeverity.Info, true),
- // Location.None));
-
- //context.ReportDiagnostic(Diagnostic.Create(
- //new DiagnosticDescriptor("PA002", "Class Found",
- //$"Processing class: {classSymbol.Name}", "Debug", DiagnosticSeverity.Warning, true),
- //Location.None));
-
- var code = BuildAccessorsForType(classSymbol, compilation, processedTypes);
-
- //System.Diagnostics.Debug.WriteLine($"Generated code for {classSymbol.Name}:\n{code}"); // 调试输出
+
+ var code = BuildAccessorsForType(classSymbol, compilation, processedTypes);
context.AddSource($"{classSymbol.Name}Extension.g.cs", code);
- var code3 = BuildAccessorsForType2(classSymbol, compilation, processedTypes);
+ var code3 = BuildAccessorsForSourceEntity(classSymbol, compilation, processedTypes);
context.AddSource($"{classSymbol.Name}Accessor.g.cs", code3);
-
- //code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
- //if (classSymbol.ContainingNamespace.ToDisplayString() == "JiShe.CollectBus.IoTDB")
- //{
-
- //}
}
// 生成工厂注册代码
@@ -183,52 +154,6 @@ namespace JiShe.CollectBus.IncrementalGenerator
return code.ToString();
}
- ///
- /// 构建类的属性访问器代码
- ///
- ///
- ///
- ///
- ///
- private static string BuildAccessorsForType2(
- INamedTypeSymbol classSymbol,
- Compilation compilation,
- HashSet processedTypes)
- {
- var code = new StringBuilder();
- code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
- code.AppendLine("// Generated code for " + classSymbol.Name);
- code.AppendLine("// ");
- code.AppendLine("#nullable enable");
- code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
- code.AppendLine();
-
- code.AppendLine($"public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>");
- code.AppendLine("{");
-
- foreach (var prop in GetAllPropertiesInHierarchy(classSymbol))
- {
- if (prop.IsIndexer) continue;
- GeneratePropertyAccessorsForType(prop, code, compilation, processedTypes);
- }
-
- code.AppendLine("}");
-
- //var code3 = $@"
- // public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>
- // {{
- // public object GetPropertyValue({classSymbol.Name} entity, string propName) => propName switch
- // {{
- // {GeneratePropertyCases(classSymbol)}
- // _ => throw new ArgumentException(""无效属性名"")
- // }};
-
- // {GenerateTupleSupport(classSymbol)}
- // }}";
-
- return code.ToString();
- }
-
///
/// 获取泛型参数
///
@@ -262,11 +187,11 @@ namespace JiShe.CollectBus.IncrementalGenerator
// 处理元组类型
if (propType is INamedTypeSymbol { IsTupleType: true } tupleType)
{
- GenerateTupleAccessors(prop, tupleType, code);
+ GenerateTupleAccessorsForType(prop, tupleType, code);
}
else if (propType is INamedTypeSymbol namedType)
{
- GenerateStandardAccessors(prop, namedType, code);
+ GenerateStandardAccessorsForType(prop, namedType, code);
ProcessNestedType(namedType, compilation, processedTypes);
}
}
@@ -277,7 +202,7 @@ namespace JiShe.CollectBus.IncrementalGenerator
///
///
///
- private static void GenerateTupleAccessors(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
+ private static void GenerateTupleAccessorsForType(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
{
var elements = tupleType.TupleElements;
var parentType = prop.ContainingType.ToDisplayString();
@@ -305,7 +230,7 @@ namespace JiShe.CollectBus.IncrementalGenerator
///
///
///
- private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
+ private static void GenerateStandardAccessorsForType(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
{
var parentType = prop.ContainingType.ToDisplayString();
code.AppendLine($" public static {propType.ToDisplayString()} Get{prop.Name}({parentType} obj) => obj.{prop.Name};");
@@ -316,7 +241,7 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
}
-
+
///
/// 处理嵌套类型
///
@@ -373,5 +298,153 @@ namespace JiShe.CollectBus.IncrementalGenerator
}
""";
}
+
+ ///
+ /// 构建实体类的源属性访问器代码
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static string BuildAccessorsForSourceEntity(
+ INamedTypeSymbol classSymbol,
+ Compilation compilation,
+ HashSet processedTypes)
+ {
+ var code = new StringBuilder();
+ code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
+ code.AppendLine("// Generated code for " + classSymbol.Name);
+ code.AppendLine("// ");
+ code.AppendLine("#nullable enable");
+ code.AppendLine("using System;");
+ code.AppendLine("using JiShe.CollectBus.Analyzers.Shared;");
+ code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
+ code.AppendLine();
+
+ code.AppendLine($"public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>");
+ code.AppendLine("{");
+
+ GetGeneratePropertyValueForSourceEntity(GetAllPropertiesInHierarchy(classSymbol), code, compilation, classSymbol);
+
+ SetGeneratePropertyValueForSourceEntity(GetAllPropertiesInHierarchy(classSymbol), code, compilation, classSymbol);
+
+ code.AppendLine("}");
+
+ return code.ToString();
+ }
+
+ private static void GetGeneratePropertyValueForSourceEntity(IEnumerable propList,
+ StringBuilder code,
+ Compilation compilation,
+ INamedTypeSymbol classSymbol)
+ {
+
+ code.AppendLine($" public object GetPropertyValue({classSymbol.Name} targetEntity, string propertyName)");
+ code.AppendLine(" {");
+ code.AppendLine(" return propertyName switch");
+ code.AppendLine(" {");
+
+ // 遍历所有属性
+ foreach (var property in propList)
+ {
+ // 安全类型转换
+ if (property.Type is not ITypeSymbol propType) continue;
+
+ // 处理元组类型
+ if (propType is INamedTypeSymbol { IsTupleType: true } tupleType)
+ {
+ }
+ else if (propType is INamedTypeSymbol namedType)
+ {
+ // 生成属性访问的
+ code.AppendLine($" \"{property.Name}\" => {classSymbol.Name}Extension.Get{property.Name}(targetEntity),");
+ }
+ }
+
+
+ code.AppendLine(" _ => throw new ArgumentException($\"Unknown property: {propertyName}\")");
+ code.AppendLine(" };");
+ code.AppendLine(" }");
+ }
+
+
+ private static void SetGeneratePropertyValueForSourceEntity(IEnumerable propList,
+ StringBuilder code,
+ Compilation compilation,
+ INamedTypeSymbol classSymbol)
+ {
+ code.AppendLine($" public void SetPropertyValue({classSymbol.Name} targetEntity, string propertyName, object value)");
+ code.AppendLine(" {");
+ code.AppendLine(" return propertyName switch");
+ code.AppendLine(" {");
+
+ // 遍历所有属性
+ foreach (var property in propList)
+ {
+ // 安全类型转换
+ if (property.Type is not ITypeSymbol propType) continue;
+
+ // 处理元组类型
+ if (propType is INamedTypeSymbol { IsTupleType: true } tupleType)
+ {
+ }
+ else if (propType is INamedTypeSymbol namedType)
+ {
+ // 生成属性设置赋值
+ code.AppendLine($" \"{property.Name}\" => {classSymbol.Name}Extension.Set{property.Name}(targetEntity,({namedType.ToDisplayString()})value),");
+
+ }
+ }
+
+
+ code.AppendLine(" _ => throw new ArgumentException($\"Unknown property: {propertyName}\")");
+ code.AppendLine(" };");
+ code.AppendLine(" }");
+ }
+
+ ///
+ /// 处理元组类型
+ ///
+ ///
+ ///
+ ///
+ private static void GenerateTupleAccessorsForSourceEntity(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
+ {
+ var elements = tupleType.TupleElements;
+ var parentType = prop.ContainingType.ToDisplayString();
+
+ for (int i = 0; i < elements.Length; i++)
+ {
+ var element = elements[i];
+ if (element.Type is not ITypeSymbol elementType) continue;
+
+ var elementName = element.CorrespondingTupleField?.Name ?? $"Item{i + 1}";
+ code.AppendLine($" public static {elementType.ToDisplayString()} Get{prop.Name}_{elementName}({parentType} obj) => obj.{prop.Name}.{elementName};");
+
+ if (prop.SetMethod != null)
+ {
+ var assignments = elements.Select((e, idx) =>
+ idx == i ? "value" : $"obj.{prop.Name}.{e.Name}");
+ code.AppendLine($" public static void Set{prop.Name}_{elementName}({parentType} obj, {elementType.ToDisplayString()} value) => obj.{prop.Name} = ({string.Join(", ", assignments)});");
+ }
+ }
+ }
+
+ ///
+ /// 生成标准属性的访问器
+ ///
+ ///
+ ///
+ ///
+ private static void GenerateStandardAccessorsForSourceEntity(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
+ {
+ var parentType = prop.ContainingType.ToDisplayString();
+ code.AppendLine($" public object {propType.ToDisplayString()} Get{prop.Name}({parentType} obj) => obj.{prop.Name};");
+
+ if (prop.SetMethod != null)
+ {
+ code.AppendLine($" public static void Set{prop.Name}({parentType} obj, {propType.ToDisplayString()} value) => obj.{prop.Name} = value;");
+ }
+ }
}
}
\ No newline at end of file
diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs
index 966f226..3355a33 100644
--- a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs
@@ -8,7 +8,7 @@ namespace JiShe.CollectBus.IoTDB.Model
/// Table模型单项数据实体
///
[EntityType(EntityTypeEnum.TableModel)]
- [SourceAnalyzers]
+ //[SourceAnalyzers]
public class TableModelSingleMeasuringEntity : IoTEntity
{
///
diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs
index 719c3c3..f59f648 100644
--- a/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs
@@ -8,7 +8,7 @@ namespace JiShe.CollectBus.IoTDB.Model
/// Tree模型单项数据实体
///
[EntityType(EntityTypeEnum.TreeModel)]
- [SourceAnalyzers]
+ //[SourceAnalyzers]
public class TreeModelSingleMeasuringEntity : IoTEntity
{
///
diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
index 79f0244..95ed072 100644
--- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
+++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
@@ -72,6 +72,8 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
};
//ElectricityMeterTreeModelExtension.GetCurrent()
//SourceEntityAccessorFactory.SetCurrent(meter);
+
+ ElectricityMeterTreeModelAccessor
await _iotDBProvider.InsertAsync(meter);
}
diff --git a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
index 3395239..2a448c1 100644
--- a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
+++ b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
@@ -22,19 +22,19 @@ namespace JiShe.CollectBus.Analyzers.Shared
///
void SetPropertyValue(T entity, string propertyName, object value);
- ///
- /// 判断是否是元组属性
- ///
- ///
- ///
- bool IsTupleProperty(string propertyName);
+ /////
+ ///// 判断是否是元组属性
+ /////
+ /////
+ /////
+ //bool IsTupleProperty(string propertyName);
- ///
- /// 获取元组属性值
- ///
- ///
- ///
- ///
- (object Item1, object Item2) GetTupleParts(T entity, string tuplePropertyName);
+ /////
+ ///// 获取元组属性值
+ /////
+ /////
+ /////
+ /////
+ //(object Item1, object Item2) GetTupleParts(T entity, string tuplePropertyName);
}
}
From 6b012d93037b5c251807dbe5520afaed3d277f56 Mon Sep 17 00:00:00 2001
From: ChenYi <296215406@outlook.com>
Date: Wed, 7 May 2025 16:37:26 +0800
Subject: [PATCH 3/6] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=A4=8D=E6=9D=82?=
=?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=A2=9E=E9=87=8F=E6=BA=90=E7=A0=81=E7=94=9F?=
=?UTF-8?q?=E6=88=90=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ComplexTypeSourceAnalyzers.cs | 526 +++++++++---------
.../Model/TableModelSingleMeasuringEntity.cs | 4 +-
.../Model/TreeModelSingleMeasuringEntity.cs | 4 +-
.../Provider/IoTDBProvider.cs | 132 +++--
.../AnalysisData/DataStorage.cs | 4 +-
.../Samples/SampleAppService.cs | 19 +-
.../BasicScheduledMeterReadingService.cs | 68 +--
.../Ammeters/ElectricityMeter.cs | 2 +-
.../Ammeters/ElectricityMeterTreeModel.cs | 3 +
.../ISourceEntityAccessor.cs | 18 +-
10 files changed, 401 insertions(+), 379 deletions(-)
diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
index 3b25aa0..804b7c0 100644
--- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
+++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
@@ -15,13 +15,11 @@ namespace JiShe.CollectBus.IncrementalGenerator
public class ComplexTypeSourceAnalyzers : IIncrementalGenerator
{
private const string AttributeFullName = "JiShe.CollectBus.Analyzers.Shared.SourceAnalyzersAttribute";
- private const string SourceEntityAccessorFactoryNamespace = "JiShe.CollectBus.Analyzers.Shared";
public void Initialize(IncrementalGeneratorInitializationContext context)
{
//Debugger.Launch();
-
// 步骤1:筛选带有 [SourceAnalyzers] 的类
var classDeclarations = context.SyntaxProvider
.CreateSyntaxProvider(
@@ -108,11 +106,6 @@ namespace JiShe.CollectBus.IncrementalGenerator
continue;
}
- var code = BuildAccessorsForType(classSymbol, compilation, processedTypes);
-
- context.AddSource($"{classSymbol.Name}Extension.g.cs", code);
-
-
var code3 = BuildAccessorsForSourceEntity(classSymbol, compilation, processedTypes);
context.AddSource($"{classSymbol.Name}Accessor.g.cs", code3);
}
@@ -120,40 +113,7 @@ namespace JiShe.CollectBus.IncrementalGenerator
// 生成工厂注册代码
context.AddSource("SourceEntityAccessorFactory.g.cs", BuildFactoryCode());
}
-
- ///
- /// 构建类的属性访问器代码
- ///
- ///
- ///
- ///
- ///
- private static string BuildAccessorsForType(
- INamedTypeSymbol classSymbol,
- Compilation compilation,
- HashSet processedTypes)
- {
- var code = new StringBuilder();
- code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
- code.AppendLine("// Generated code for " + classSymbol.Name);
- code.AppendLine("// ");
- code.AppendLine("#nullable enable");
- code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
- code.AppendLine();
-
- code.AppendLine($"public static class {classSymbol.Name}Extension{GetGenericParams(classSymbol)}");
- code.AppendLine("{");
-
- foreach (var prop in GetAllPropertiesInHierarchy(classSymbol))
- {
- if (prop.IsIndexer) continue;
- GeneratePropertyAccessorsForType(prop, code, compilation, processedTypes);
- }
-
- code.AppendLine("}");
- return code.ToString();
- }
-
+
///
/// 获取泛型参数
///
@@ -165,72 +125,15 @@ namespace JiShe.CollectBus.IncrementalGenerator
var parameters = symbol.TypeParameters.Select(t => t.Name);
return $"<{string.Join(", ", parameters)}>";
}
-
- ///
- /// 生成属性访问器代码
- ///
- ///
- ///
- ///
- ///
- private static void GeneratePropertyAccessorsForType(
- IPropertySymbol prop,
- StringBuilder code,
- Compilation compilation,
- HashSet processedTypes)
- {
- // 安全类型转换
- if (prop.Type is not ITypeSymbol propType) return;
-
- code.AppendLine($" // Processing property: {prop.Name}");
-
- // 处理元组类型
- if (propType is INamedTypeSymbol { IsTupleType: true } tupleType)
- {
- GenerateTupleAccessorsForType(prop, tupleType, code);
- }
- else if (propType is INamedTypeSymbol namedType)
- {
- GenerateStandardAccessorsForType(prop, namedType, code);
- ProcessNestedType(namedType, compilation, processedTypes);
- }
- }
-
- ///
- /// 处理元组类型
- ///
- ///
- ///
- ///
- private static void GenerateTupleAccessorsForType(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
- {
- var elements = tupleType.TupleElements;
- var parentType = prop.ContainingType.ToDisplayString();
-
- for (int i = 0; i < elements.Length; i++)
- {
- var element = elements[i];
- if (element.Type is not ITypeSymbol elementType) continue;
-
- var elementName = element.CorrespondingTupleField?.Name ?? $"Item{i + 1}";
- code.AppendLine($" public static {elementType.ToDisplayString()} Get{prop.Name}_{elementName}({parentType} obj) => obj.{prop.Name}.{elementName};");
-
- if (prop.SetMethod != null)
- {
- var assignments = elements.Select((e, idx) =>
- idx == i ? "value" : $"obj.{prop.Name}.{e.Name}");
- code.AppendLine($" public static void Set{prop.Name}_{elementName}({parentType} obj, {elementType.ToDisplayString()} value) => obj.{prop.Name} = ({string.Join(", ", assignments)});");
- }
- }
- }
-
+
+
///
/// 生成标准属性的访问器
///
///
///
///
- private static void GenerateStandardAccessorsForType(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
+ private static void GenerateStandardAccessors(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
{
var parentType = prop.ContainingType.ToDisplayString();
code.AppendLine($" public static {propType.ToDisplayString()} Get{prop.Name}({parentType} obj) => obj.{prop.Name};");
@@ -240,211 +143,318 @@ namespace JiShe.CollectBus.IncrementalGenerator
code.AppendLine($" public static void Set{prop.Name}({parentType} obj, {propType.ToDisplayString()} value) => obj.{prop.Name} = value;");
}
}
-
+
///
- /// 处理嵌套类型
+ /// 构建实体访问器代码(支持泛型)
///
- ///
- ///
- ///
- private static void ProcessNestedType(ITypeSymbol typeSymbol, Compilation compilation, HashSet processedTypes)
- {
- if (typeSymbol is not INamedTypeSymbol namedType) return;
- if (!ShouldProcessNestedType(namedType)) return;
- if (!processedTypes.Add(namedType)) return;
-
- var code = BuildAccessorsForType(namedType, compilation, processedTypes);
- }
-
- ///
- /// 处理嵌套类型
- ///
- ///
- ///
- private static bool ShouldProcessNestedType(INamedTypeSymbol symbol)
- {
- return symbol.DeclaredAccessibility == Accessibility.Public &&
- !symbol.IsTupleType &&
- !symbol.IsAnonymousType &&
- !symbol.IsImplicitlyDeclared &&
- !symbol.Name.StartsWith("<");
- }
-
- ///
- /// 生成扩展类工厂代码
- ///
- ///
- private static string BuildFactoryCode()
- {
- return """
- using System;
- using System.Collections.Concurrent;
- namespace JiShe.CollectBus.Analyzers.Shared;
- public static class SourceEntityAccessorFactory
- {
- private static readonly ConcurrentDictionary _accessors = new();
-
- public static ISourceEntityAccessor GetAccessor()
- {
- if (!_accessors.TryGetValue(typeof(T), out var accessor))
- {
- accessor = Activator.CreateInstance(
- Type.GetType($"{typeof(T).Namespace}.{typeof(T).Name}Accessor")!)!;
- _accessors.TryAdd(typeof(T), accessor);
- }
- return (ISourceEntityAccessor)accessor!;
- }
- }
- """;
- }
-
- ///
- /// 构建实体类的源属性访问器代码
- ///
- ///
- ///
- ///
- ///
private static string BuildAccessorsForSourceEntity(
- INamedTypeSymbol classSymbol,
- Compilation compilation,
- HashSet processedTypes)
+ INamedTypeSymbol classSymbol,
+ Compilation compilation,
+ HashSet processedTypes)
{
var code = new StringBuilder();
- code.AppendLine("#pragma warning disable CS0419 // 禁用警告");
- code.AppendLine("// Generated code for " + classSymbol.Name);
code.AppendLine("// ");
code.AppendLine("#nullable enable");
code.AppendLine("using System;");
+ code.AppendLine("using System.Collections.Generic;");
code.AppendLine("using JiShe.CollectBus.Analyzers.Shared;");
code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
code.AppendLine();
- code.AppendLine($"public sealed class {classSymbol.Name}Accessor : ISourceEntityAccessor<{classSymbol.Name}>");
- code.AppendLine("{");
-
- GetGeneratePropertyValueForSourceEntity(GetAllPropertiesInHierarchy(classSymbol), code, compilation, classSymbol);
+ // 处理泛型类型参数
+ var genericParams = classSymbol.IsGenericType
+ ? $"<{string.Join(", ", classSymbol.TypeParameters.Select(t => t.Name))}>"
+ : "";
+
+ code.AppendLine(
+ $"public sealed class {classSymbol.Name}Accessor{genericParams} " +
+ $": ISourceEntityAccessor<{classSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>");
+
+ code.AppendLine("{");
+
+ var propList = GetAllPropertiesInHierarchy(classSymbol);
+
+ foreach (var prop in propList)
+ {
+ // 安全类型转换
+ if (prop.Type is not ITypeSymbol propType) continue;
+
+ if (propType is INamedTypeSymbol { IsTupleType: true } tupleType)
+ {
+ GenerateTupleAccessors(prop, tupleType, code, classSymbol);
+ }
+ else if (propType is INamedTypeSymbol namedType)
+ {
+ GenerateStandardAccessors(prop, namedType, code);
+ }
+ }
+
+ //生成当前类属性名称集合
+ GeneratePropertyListForSourceEntity(propList, code, compilation, classSymbol);
+
+
+ //生成当前类属性访问
+ GetGeneratePropertyValueForSourceEntity(
+ propList,
+ code,
+ compilation,
+ classSymbol);
+
+ //生成当前类属性设置
+ SetGeneratePropertyValueForSourceEntity(
+ propList,
+ code,
+ compilation,
+ classSymbol);
+
- SetGeneratePropertyValueForSourceEntity(GetAllPropertiesInHierarchy(classSymbol), code, compilation, classSymbol);
code.AppendLine("}");
-
return code.ToString();
}
- private static void GetGeneratePropertyValueForSourceEntity(IEnumerable propList,
+ ///
+ /// 生成泛型ValueTuple 元组访问器
+ ///
+ private static void GenerateTupleAccessors(
+ IPropertySymbol prop,
+ INamedTypeSymbol tupleType,
+ StringBuilder code,
+ INamedTypeSymbol classSymbol)
+ {
+ var parentType = classSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ var tupleElements = tupleType.TupleElements;
+
+ for (int i = 0; i < tupleElements.Length; i++)
+ {
+ var element = tupleElements[i];
+ var elementType = element.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ var elementName = element.Name;
+
+ // Getter保持不变
+ code.AppendLine(
+ $" public static {elementType} Get{prop.Name}_{elementName}" +
+ $"({parentType} obj) => obj.{prop.Name}.{elementName};");
+
+ // Setter修复:使用元组字面量
+ if (prop.SetMethod != null)
+ {
+ var valueExpressions = tupleElements.Select((e, idx) =>
+ idx == i ? "value" : $"obj.{prop.Name}.{e.Name}"
+ ).ToList();
+
+ // 关键修复:生成正确的元组字面量表达式
+ code.AppendLine(
+ $" public static void Set{prop.Name}_{elementName}" +
+ $"({parentType} obj, {elementType} value) => " +
+ $"obj.{prop.Name} = ({string.Join(", ", valueExpressions)});");
+ }
+ }
+ }
+
+ ///
+ /// 处理System.Tuple类型的访问器生成
+ ///
+ private static void GenerateSystemTupleAccessors(
+ IPropertySymbol prop,
+ INamedTypeSymbol tupleType,
+ StringBuilder code,
+ INamedTypeSymbol classSymbol)
+ {
+ var parentType = classSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ var elementTypes = tupleType.TypeArguments;
+ var tupleTypeName = tupleType.ToDisplayString();
+
+ for (int i = 0; i < elementTypes.Length; i++)
+ {
+ var elementType = elementTypes[i].ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ var elementName = $"Item{i + 1}";
+
+ // Getter
+ code.AppendLine(
+ $" public static {elementType} Get{prop.Name}_{elementName}" +
+ $"({parentType} obj) => obj.{prop.Name}.{elementName};");
+
+ // Setter
+ if (prop.SetMethod != null)
+ {
+ var assignments = elementTypes.Select((_, idx) =>
+ idx == i ? "value" : $"obj.{prop.Name}.Item{idx + 1}"
+ ).ToList();
+
+ code.AppendLine(
+ $" public static void Set{prop.Name}_{elementName}" +
+ $"({parentType} obj, {elementType} value) => " +
+ $"obj.{prop.Name} = new {tupleTypeName}({string.Join(", ", assignments)});");
+ }
+ }
+ }
+
+ ///
+ /// 增强的工厂类实现
+ ///
+ private static string BuildFactoryCode()
+ {
+ return """
+ using System;
+ using System.Collections.Concurrent;
+ using System.Reflection;
+
+ namespace JiShe.CollectBus.Analyzers.Shared;
+
+ public static class SourceEntityAccessorFactory
+ {
+ private static readonly ConcurrentDictionary _accessors = new();
+
+ public static ISourceEntityAccessor GetAccessor()
+ {
+ return (ISourceEntityAccessor)_accessors.GetOrAdd(typeof(T), t =>
+ {
+ var typeName = $"{t.Namespace}.{t.Name}Accessor";
+ if (t.IsGenericType)
+ {
+ var genericArgs = t.GetGenericArguments();
+ var genericDef = t.GetGenericTypeDefinition();
+ typeName = $"{genericDef.Namespace}.{genericDef.Name}Accessor`{genericArgs.Length}";
+ }
+
+ var type = Type.GetType(typeName)
+ ?? Assembly.GetAssembly(t)?.GetType(typeName)
+ ?? throw new InvalidOperationException($"Accessor type {typeName} not found");
+
+ return t.IsGenericType
+ ? Activator.CreateInstance(type.MakeGenericType(t.GetGenericArguments()))
+ : Activator.CreateInstance(type);
+ });
+ }
+ }
+ """;
+ }
+
+ ///
+ /// 属性访问生成逻辑
+ ///
+ /// 属性集合
+ ///
+ ///
+ ///
+ private static void GetGeneratePropertyValueForSourceEntity(
+ IEnumerable propList,
StringBuilder code,
Compilation compilation,
INamedTypeSymbol classSymbol)
{
-
- code.AppendLine($" public object GetPropertyValue({classSymbol.Name} targetEntity, string propertyName)");
+ code.AppendLine($" public object GetPropertyValue({classSymbol} targetEntity, string propertyName)");
+ code.AppendLine(" {");
+ code.AppendLine(" return propertyName switch");
code.AppendLine(" {");
- code.AppendLine(" return propertyName switch");
- code.AppendLine(" {");
- // 遍历所有属性
- foreach (var property in propList)
- {
- // 安全类型转换
- if (property.Type is not ITypeSymbol propType) continue;
-
- // 处理元组类型
- if (propType is INamedTypeSymbol { IsTupleType: true } tupleType)
- {
- }
- else if (propType is INamedTypeSymbol namedType)
- {
- // 生成属性访问的
- code.AppendLine($" \"{property.Name}\" => {classSymbol.Name}Extension.Get{property.Name}(targetEntity),");
- }
- }
-
-
- code.AppendLine(" _ => throw new ArgumentException($\"Unknown property: {propertyName}\")");
- code.AppendLine(" };");
- code.AppendLine(" }");
- }
-
-
- private static void SetGeneratePropertyValueForSourceEntity(IEnumerable propList,
- StringBuilder code,
- Compilation compilation,
- INamedTypeSymbol classSymbol)
- {
- code.AppendLine($" public void SetPropertyValue({classSymbol.Name} targetEntity, string propertyName, object value)");
- code.AppendLine(" {");
- code.AppendLine(" return propertyName switch");
- code.AppendLine(" {");
-
- // 遍历所有属性
- foreach (var property in propList)
+ foreach (var prop in propList)
{
- // 安全类型转换
- if (property.Type is not ITypeSymbol propType) continue;
-
- // 处理元组类型
- if (propType is INamedTypeSymbol { IsTupleType: true } tupleType)
- {
- }
- else if (propType is INamedTypeSymbol namedType)
+ if (prop.Type is INamedTypeSymbol { IsTupleType: true } tupleType)
{
- // 生成属性设置赋值
- code.AppendLine($" \"{property.Name}\" => {classSymbol.Name}Extension.Set{property.Name}(targetEntity,({namedType.ToDisplayString()})value),");
-
- }
+ foreach (var element in tupleType.TupleElements)
+ {
+ code.AppendLine(
+ $" \"{prop.Name}.{element.Name}\" => " +
+ $"Get{prop.Name}_{element.Name}(targetEntity),");
+ }
+ }
+ else
+ {
+ code.AppendLine(
+ $" \"{prop.Name}\" => " +
+ $"Get{prop.Name}(targetEntity),");
+ }
}
-
- code.AppendLine(" _ => throw new ArgumentException($\"Unknown property: {propertyName}\")");
- code.AppendLine(" };");
- code.AppendLine(" }");
+ code.AppendLine(" _ => throw new ArgumentException($\"Unknown property: {propertyName}\")");
+ code.AppendLine(" };");
+ code.AppendLine(" }");
}
///
- /// 处理元组类型
+ /// 属性设置生成逻辑
///
- ///
- ///
+ /// 属性集合
///
- private static void GenerateTupleAccessorsForSourceEntity(IPropertySymbol prop, INamedTypeSymbol tupleType, StringBuilder code)
+ ///
+ ///
+ private static void SetGeneratePropertyValueForSourceEntity(
+ IEnumerable propList,
+ StringBuilder code,
+ Compilation compilation,
+ INamedTypeSymbol classSymbol)
{
- var elements = tupleType.TupleElements;
- var parentType = prop.ContainingType.ToDisplayString();
+ code.AppendLine($" public void SetPropertyValue({classSymbol} targetEntity, string propertyName, object value)");
+ code.AppendLine(" {");
+ code.AppendLine(" switch (propertyName)");
+ code.AppendLine(" {");
- for (int i = 0; i < elements.Length; i++)
+ foreach (var prop in propList)
{
- var element = elements[i];
- if (element.Type is not ITypeSymbol elementType) continue;
-
- var elementName = element.CorrespondingTupleField?.Name ?? $"Item{i + 1}";
- code.AppendLine($" public static {elementType.ToDisplayString()} Get{prop.Name}_{elementName}({parentType} obj) => obj.{prop.Name}.{elementName};");
-
- if (prop.SetMethod != null)
+ if (prop.Type is INamedTypeSymbol { IsTupleType: true } tupleType)
{
- var assignments = elements.Select((e, idx) =>
- idx == i ? "value" : $"obj.{prop.Name}.{e.Name}");
- code.AppendLine($" public static void Set{prop.Name}_{elementName}({parentType} obj, {elementType.ToDisplayString()} value) => obj.{prop.Name} = ({string.Join(", ", assignments)});");
+ foreach (var element in tupleType.TupleElements)
+ {
+ var elementType = element.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ code.AppendLine($" case \"{prop.Name}.{element.Name}\":");
+ code.AppendLine($" Set{prop.Name}_{element.Name}(");
+ code.AppendLine($" targetEntity, ({elementType})value);");
+ code.AppendLine(" break;");
+ }
+ }
+ else if (prop.SetMethod != null)
+ {
+ var propType = prop.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ code.AppendLine($" case \"{prop.Name}\":");
+ code.AppendLine($" Set{prop.Name}(");
+ code.AppendLine($" targetEntity, ({propType})value);");
+ code.AppendLine(" break;");
}
}
+
+ code.AppendLine(" default:");
+ code.AppendLine(" throw new ArgumentException($\"Unknown property: {propertyName}\");");
+ code.AppendLine(" }");
+ code.AppendLine(" }");
}
///
- /// 生成标准属性的访问器
+ /// 属性名称集合
///
- ///
- ///
+ /// 属性集合
///
- private static void GenerateStandardAccessorsForSourceEntity(IPropertySymbol prop, INamedTypeSymbol propType, StringBuilder code)
+ ///
+ ///
+ private static void GeneratePropertyListForSourceEntity(
+ IEnumerable propList,
+ StringBuilder code,
+ Compilation compilation,
+ INamedTypeSymbol classSymbol)
{
- var parentType = prop.ContainingType.ToDisplayString();
- code.AppendLine($" public object {propType.ToDisplayString()} Get{prop.Name}({parentType} obj) => obj.{prop.Name};");
-
- if (prop.SetMethod != null)
+ code.AppendLine(" public List PropertyList {get;} = new List()");
+ code.AppendLine(" {");
+ List tempPropList = new List();
+ foreach (var prop in propList)
{
- code.AppendLine($" public static void Set{prop.Name}({parentType} obj, {propType.ToDisplayString()} value) => obj.{prop.Name} = value;");
+ if (prop.Type is INamedTypeSymbol { IsTupleType: true } tupleType)
+ {
+ foreach (var element in tupleType.TupleElements)
+ {
+ tempPropList.Add($"\"{prop.Name}.{element.Name}\"");
+ }
+ }
+ else
+ {
+ tempPropList.Add($"\"{prop.Name}\"");
+ }
}
+
+ code.Append(string.Join(",", tempPropList));
+
+ code.AppendLine(" };");
}
}
}
\ No newline at end of file
diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs
index 3355a33..ed0fd4d 100644
--- a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntity.cs
@@ -8,13 +8,13 @@ namespace JiShe.CollectBus.IoTDB.Model
/// Table模型单项数据实体
///
[EntityType(EntityTypeEnum.TableModel)]
- //[SourceAnalyzers]
+ [SourceAnalyzers]
public class TableModelSingleMeasuringEntity : IoTEntity
{
///
/// 单项数据键值对
///
[SingleMeasuring(nameof(SingleColumn))]
- public required Tuple SingleColumn { get; set; }
+ public required ValueTuple SingleColumn { get; set; }
}
}
diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs b/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs
index f59f648..c87516c 100644
--- a/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Model/TreeModelSingleMeasuringEntity.cs
@@ -8,13 +8,13 @@ namespace JiShe.CollectBus.IoTDB.Model
/// Tree模型单项数据实体
///
[EntityType(EntityTypeEnum.TreeModel)]
- //[SourceAnalyzers]
+ [SourceAnalyzers]
public class TreeModelSingleMeasuringEntity : IoTEntity
{
///
/// 单项数据键值对
///
[SingleMeasuring(nameof(SingleMeasuring))]
- public required Tuple SingleMeasuring { get; set; }
+ public required ValueTuple SingleMeasuring { get; set; }
}
}
diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs
index d867674..aebce66 100644
--- a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs
@@ -20,6 +20,7 @@ using JiShe.CollectBus.IoTDB.Options;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
+using JiShe.CollectBus.Analyzers.Shared;
namespace JiShe.CollectBus.IoTDB.Provider
{
@@ -176,6 +177,8 @@ namespace JiShe.CollectBus.IoTDB.Provider
///
public async Task GetMetadata() where T : IoTEntity
{
+ var accessor = SourceEntityAccessorFactory.GetAccessor();
+
var columns = CollectColumnMetadata(typeof(T));
var metadata = BuildDeviceMetadata(columns);
var metaData = MetadataCache.AddOrUpdate(
@@ -260,6 +263,8 @@ namespace JiShe.CollectBus.IoTDB.Provider
List tempColumnNames = new List();
tempColumnNames.AddRange(metadata.ColumnNames);
+ var accessor = SourceEntityAccessorFactory.GetAccessor();
+
var entityTypeAttribute = typeof(T).GetCustomAttribute();
if (entityTypeAttribute == null)
@@ -295,69 +300,74 @@ namespace JiShe.CollectBus.IoTDB.Provider
foreach (var measurement in tempColumnNames)
{
-
- PropertyInfo propertyInfo = typeof(T).GetProperty(measurement);
- if (propertyInfo == null)
- {
- throw new Exception($"{nameof(BuildTablet)} 构建表模型{typeof(T).Name}时,没有找到{measurement}属性,属于异常情况,-101。");
- }
-
- var value = propertyInfo.GetValue(entity);
- if (propertyInfo.IsDefined(typeof(SingleMeasuringAttribute), false) && metadata.IsSingleMeasuring == true)//表示当前对象是单测点模式
- {
- if (value != null)
- {
- Type tupleType = value.GetType();
- Type[] tupleArgs = tupleType.GetGenericArguments();
- Type item2Type = tupleArgs[1]; // T 的实际类型
- var item1 = tupleType.GetProperty("Item1")!.GetValue(value);
- var item2 = tupleType.GetProperty("Item2")!.GetValue(value);
- if (item1 == null || item2 == null)
- {
- throw new Exception($"{nameof(BuildTablet)} 构建表模型{typeof(T).Name}时,单测点模式构建失败,没有获取测点名称或者测点值,-102。");
- }
-
- var indexOf = metadata.ColumnNames.IndexOf(measurement);
- metadata.ColumnNames[indexOf] = (string)item1!;
-
- rowValues.Add(item2);
- }
- else
- {
- rowValues.Add(null);
- }
-
- //同时如果是单测点模式,且是table模型存储,路径只能通过DevicePathBuilder.GetDeviceTableName(entity)获取
- if (_runtimeContext.UseTableSessionPool)
- {
- tableNameOrTreePath = DevicePathBuilder.GetDeviceTableName(entity);
- }
- }
- else
- {
-
- //需要根据value的类型,进行相应的值映射转换,例如datetime转换为long的时间戳值
- if (value != null)
- {
- Type tupleType = value.GetType();
- var tempValue = tupleType.Name.ToUpper() switch
- {
- "DATETIME" => Convert.ToDateTime(value).GetDateTimeOffset().ToUnixTimeNanoseconds(),
- _ => value
- };
-
- rowValues.Add(tempValue);
- }
- else
- {
- rowValues.Add(value);
- }
-
- }
-
+ rowValues.Add(accessor.GetPropertyValue(entity,measurement));
}
- values.Add(rowValues);
+ //foreach (var measurement in tempColumnNames)
+ //{
+
+ // PropertyInfo propertyInfo = typeof(T).GetProperty(measurement);
+ // if (propertyInfo == null)
+ // {
+ // throw new Exception($"{nameof(BuildTablet)} 构建表模型{typeof(T).Name}时,没有找到{measurement}属性,属于异常情况,-101。");
+ // }
+
+ // var value = propertyInfo.GetValue(entity);
+ // if (propertyInfo.IsDefined(typeof(SingleMeasuringAttribute), false) && metadata.IsSingleMeasuring == true)//表示当前对象是单测点模式
+ // {
+ // if (value != null)
+ // {
+ // Type tupleType = value.GetType();
+ // Type[] tupleArgs = tupleType.GetGenericArguments();
+ // Type item2Type = tupleArgs[1]; // T 的实际类型
+ // var item1 = tupleType.GetProperty("Item1")!.GetValue(value);
+ // var item2 = tupleType.GetProperty("Item2")!.GetValue(value);
+ // if (item1 == null || item2 == null)
+ // {
+ // throw new Exception($"{nameof(BuildTablet)} 构建表模型{typeof(T).Name}时,单测点模式构建失败,没有获取测点名称或者测点值,-102。");
+ // }
+
+ // var indexOf = metadata.ColumnNames.IndexOf(measurement);
+ // metadata.ColumnNames[indexOf] = (string)item1!;
+
+ // rowValues.Add(item2);
+ // }
+ // else
+ // {
+ // rowValues.Add(null);
+ // }
+
+ // //同时如果是单测点模式,且是table模型存储,路径只能通过DevicePathBuilder.GetDeviceTableName(entity)获取
+ // if (_runtimeContext.UseTableSessionPool)
+ // {
+ // tableNameOrTreePath = DevicePathBuilder.GetDeviceTableName(entity);
+ // }
+ // }
+ // else
+ // {
+
+ // //需要根据value的类型,进行相应的值映射转换,例如datetime转换为long的时间戳值
+ // if (value != null)
+ // {
+ // Type tupleType = value.GetType();
+ // var tempValue = tupleType.Name.ToUpper() switch
+ // {
+ // "DATETIME" => Convert.ToDateTime(value).GetDateTimeOffset().ToUnixTimeNanoseconds(),
+ // _ => value
+ // };
+
+ // rowValues.Add(tempValue);
+ // }
+ // else
+ // {
+ // rowValues.Add(value);
+ // }
+
+ // }
+
+ //}
+
+ values.Add(rowValues);
//如果指定了路径
if (!string.IsNullOrWhiteSpace(tableNameOrTreePath))
diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs
index 00435e0..3b3816a 100644
--- a/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs
+++ b/protocols/JiShe.CollectBus.Protocol.T37612012/AnalysisData/DataStorage.cs
@@ -90,7 +90,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
DeviceType = $"{data.MeterType}",
ProjectId = $"{data.ProjectId}",
Timestamps = data.TimeSpan!.Value.GetFormatTime(analysisBaseDto.DensityUnit, analysisBaseDto.TimeDensity).GetDateTimeOffset().ToUnixTimeMilliseconds(),
- SingleMeasuring = new Tuple(data.FiledName ?? string.Empty, data.DataValue ?? default)
+ SingleMeasuring = (data.FiledName ?? string.Empty, data.DataValue ?? default)
};
_runtimeContext.UseTableSessionPool = true; // 使用表模型池
var taskSendInfo = await _dbProvider.QueryAsync(new IoTDBQueryOptions() { TableNameOrTreePath = DevicePathBuilder.GetTableName(), Conditions = conditions, PageIndex = 0, PageSize = 1 });
@@ -193,7 +193,7 @@ namespace JiShe.CollectBus.Protocol.T37612012.AnalysisData
DeviceType = $"{item.MeterType}",
ProjectId = $"{item.ProjectId}",
Timestamps = item.TimeSpan!.Value.GetFormatTime(analysisBaseDto.DensityUnit, analysisBaseDto.TimeDensity).GetDateTimeOffset().ToUnixTimeMilliseconds(), // TODO:这里暂时格式化15分钟数据,需要进行调整
- SingleMeasuring = new Tuple(item.FiledName ?? string.Empty, item.DataValue ?? default)
+ SingleMeasuring = (item.FiledName ?? string.Empty, item.DataValue ?? default)
};
_runtimeContext.UseTableSessionPool = true; // 使用表模型池
var taskSendInfo = await _dbProvider.QueryAsync(new IoTDBQueryOptions() { TableNameOrTreePath = DevicePathBuilder.GetTableName(), Conditions = conditions, PageIndex = 0, PageSize = 1 });
diff --git a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
index 95ed072..ef3b894 100644
--- a/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
+++ b/services/JiShe.CollectBus.Application/Samples/SampleAppService.cs
@@ -73,7 +73,9 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
//ElectricityMeterTreeModelExtension.GetCurrent()
//SourceEntityAccessorFactory.SetCurrent(meter);
- ElectricityMeterTreeModelAccessor
+ //ElectricityMeterTreeModelAccessor.
+ //TableModelSingleMeasuringEntityExtension
+ //TableModelSingleMeasuringEntityAccessor.GetSystemName(meter);
await _iotDBProvider.InsertAsync(meter);
}
@@ -172,6 +174,8 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
[HttpGet]
public async Task TestTreeModelSingleMeasuringEntity(string measuring, string value, DateTime time)
{
+ time = DateTime.Now;
+
var meter = new TreeModelSingleMeasuringEntity()
{
SystemName = "energy",
@@ -179,7 +183,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
DeviceType = "1",
ProjectId = "10059",
Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(),
- SingleMeasuring = new Tuple(measuring, value)
+ SingleMeasuring = (measuring, value)
};
await _iotDBProvider.InsertAsync(meter);
}
@@ -192,6 +196,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
[HttpGet]
public async Task TestTreeModelSingleMeasuringEntity2(string measuring, int value, DateTime time)
{
+ time = DateTime.Now;
var meter = new TreeModelSingleMeasuringEntity()
{
SystemName = "energy",
@@ -199,7 +204,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
DeviceType = "Ammeter",
ProjectId = "10059",
Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(),
- SingleMeasuring = new Tuple(measuring, value)
+ SingleMeasuring = (measuring, value)
};
await _iotDBProvider.InsertAsync(meter);
}
@@ -212,6 +217,8 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
[HttpGet]
public async Task TestTableModelSingleMeasuringEntity(string measuring, string value, DateTime time)
{
+ time = DateTime.Now;
+
var meter = new TableModelSingleMeasuringEntity()
{
SystemName = "energy",
@@ -219,7 +226,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
DeviceType = "Ammeter",
ProjectId = "10059",
Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(),
- SingleColumn = new Tuple(measuring, value)
+ SingleColumn = (measuring, value)
};
_dbContext.UseTableSessionPool = true;
await _iotDBProvider.InsertAsync(meter);
@@ -233,6 +240,8 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
[HttpGet]
public async Task TestTableModelSingleMeasuringEntity2(string measuring, int value, DateTime time)
{
+ time = DateTime.Now;
+
var meter = new TableModelSingleMeasuringEntity()
{
SystemName = "energy",
@@ -240,7 +249,7 @@ public class SampleAppService : CollectBusAppService, ISampleAppService, IKafkaS
DeviceType = "Ammeter",
ProjectId = "10059",
Timestamps = time.GetDateTimeOffset().ToUnixTimeMilliseconds(),
- SingleColumn = new Tuple(measuring, value)
+ SingleColumn = (measuring, value)
};
_dbContext.UseTableSessionPool = true;
await _iotDBProvider.InsertAsync(meter);
diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
index 47b8a99..e75ad84 100644
--- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
+++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
@@ -336,47 +336,47 @@ namespace JiShe.CollectBus.ScheduledMeterReading
//此处代码不要删除
#if DEBUG
- var timeDensity = "15";
- var serverTagName = "JiSheCollectBus2";
- var redisCacheMeterInfoHashKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoHashKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
- var redisCacheMeterInfoSetIndexKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoSetIndexKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
- var redisCacheMeterInfoZSetScoresIndexKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoZSetScoresIndexKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
+ //var timeDensity = "15";
+ //var serverTagName = "JiSheCollectBus2";
+ //var redisCacheMeterInfoHashKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoHashKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
+ //var redisCacheMeterInfoSetIndexKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoSetIndexKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
+ //var redisCacheMeterInfoZSetScoresIndexKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoZSetScoresIndexKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
List meterInfos = new List();
- List focusAddressDataLista = new List();
- var timer1 = Stopwatch.StartNew();
+ //List focusAddressDataLista = new List();
+ //var timer1 = Stopwatch.StartNew();
- var allIds = new HashSet();
- decimal? score = null;
- string member = null;
+ //var allIds = new HashSet();
+ //decimal? score = null;
+ //string member = null;
- while (true)
- {
- var page = await _redisDataCacheService.GetAllPagedData(
- redisCacheMeterInfoHashKeyTemp,
- redisCacheMeterInfoZSetScoresIndexKeyTemp,
- pageSize: 1000,
- lastScore: score,
- lastMember: member);
+ //while (true)
+ //{
+ // var page = await _redisDataCacheService.GetAllPagedData(
+ // redisCacheMeterInfoHashKeyTemp,
+ // redisCacheMeterInfoZSetScoresIndexKeyTemp,
+ // pageSize: 1000,
+ // lastScore: score,
+ // lastMember: member);
- meterInfos.AddRange(page.Items);
- focusAddressDataLista.AddRange(page.Items.Select(d => $"{d.MeterId}"));
- foreach (var item in page.Items)
- {
- if (!allIds.Add(item.MemberId))
- {
- _logger.LogError($"{item.MemberId}Duplicate data found!");
- }
- }
- if (!page.HasNext) break;
- score = page.NextScore;
- member = page.NextMember;
- }
+ // meterInfos.AddRange(page.Items);
+ // focusAddressDataLista.AddRange(page.Items.Select(d => $"{d.MeterId}"));
+ // foreach (var item in page.Items)
+ // {
+ // if (!allIds.Add(item.MemberId))
+ // {
+ // _logger.LogError($"{item.MemberId}Duplicate data found!");
+ // }
+ // }
+ // if (!page.HasNext) break;
+ // score = page.NextScore;
+ // member = page.NextMember;
+ //}
- timer1.Stop();
- _logger.LogError($"电表初始化读取数据总共花费时间{timer1.ElapsedMilliseconds}毫秒");
- DeviceGroupBalanceControl.InitializeCache(focusAddressDataLista, _kafkaOptions.NumPartitions);
+ //timer1.Stop();
+ //_logger.LogError($"电表初始化读取数据总共花费时间{timer1.ElapsedMilliseconds}毫秒");
+ //DeviceGroupBalanceControl.InitializeCache(focusAddressDataLista, _kafkaOptions.NumPartitions);
return;
#else
var meterInfos = await GetAmmeterInfoList(gatherCode);
diff --git a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs
index 9ba3c94..c04a554 100644
--- a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs
+++ b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeter.cs
@@ -6,7 +6,7 @@ using JiShe.CollectBus.IoTDB.Model;
namespace JiShe.CollectBus.Ammeters
{
[EntityType(EntityTypeEnum.TableModel)]
- [SourceAnalyzers]
+ //[SourceAnalyzers]
public class ElectricityMeter : IoTEntity
{
[ATTRIBUTEColumn]
diff --git a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs
index 1f11198..38d3ee6 100644
--- a/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs
+++ b/services/JiShe.CollectBus.Domain/Ammeters/ElectricityMeterTreeModel.cs
@@ -2,6 +2,7 @@
using JiShe.CollectBus.IoTDB.Attribute;
using JiShe.CollectBus.IoTDB.Enums;
using JiShe.CollectBus.IoTDB.Model;
+using System;
namespace JiShe.CollectBus.Ammeters
{
@@ -35,5 +36,7 @@ namespace JiShe.CollectBus.Ammeters
[FIELDColumn]
public double? Currentd { get; set; }
+
+ public Tuple TupleData { get; set;}
}
}
diff --git a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
index 2a448c1..baff180 100644
--- a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
+++ b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
@@ -22,19 +22,9 @@ namespace JiShe.CollectBus.Analyzers.Shared
///
void SetPropertyValue(T entity, string propertyName, object value);
- /////
- ///// 判断是否是元组属性
- /////
- /////
- /////
- //bool IsTupleProperty(string propertyName);
-
- /////
- ///// 获取元组属性值
- /////
- /////
- /////
- /////
- //(object Item1, object Item2) GetTupleParts(T entity, string tuplePropertyName);
+ ///
+ /// 属性名称集合
+ ///
+ List PropertyList { get; }
}
}
From ff517664fe1091c8011f0432f11192722c654be4 Mon Sep 17 00:00:00 2001
From: ChenYi <296215406@outlook.com>
Date: Wed, 7 May 2025 17:20:10 +0800
Subject: [PATCH 4/6] =?UTF-8?q?=E5=A4=8D=E6=9D=82=E7=B1=BB=E5=9E=8B?=
=?UTF-8?q?=E5=A2=9E=E9=87=8F=E6=BA=90=E7=94=9F=E6=88=90=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ComplexTypeSourceAnalyzers.cs | 46 +++++++----
...TableModelSingleMeasuringEntityAccessor.cs | 77 +++++++++++++++++++
.../Provider/IoTDBProvider.cs | 9 ++-
3 files changed, 113 insertions(+), 19 deletions(-)
create mode 100644 modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs
diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
index 804b7c0..195175a 100644
--- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
+++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
@@ -162,13 +162,19 @@ namespace JiShe.CollectBus.IncrementalGenerator
code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
code.AppendLine();
- // 处理泛型类型参数
+ // 处理泛型类型名称
+ var accessibility = classSymbol.DeclaredAccessibility switch
+ {
+ Accessibility.Public => "public",
+ _ => "internal"
+ };
+
var genericParams = classSymbol.IsGenericType
? $"<{string.Join(", ", classSymbol.TypeParameters.Select(t => t.Name))}>"
: "";
code.AppendLine(
- $"public sealed class {classSymbol.Name}Accessor{genericParams} " +
+ $"{accessibility} sealed class {classSymbol.Name}Accessor{genericParams} " + // 保留泛型参数
$": ISourceEntityAccessor<{classSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>");
code.AppendLine("{");
@@ -306,26 +312,32 @@ namespace JiShe.CollectBus.IncrementalGenerator
public static class SourceEntityAccessorFactory
{
private static readonly ConcurrentDictionary _accessors = new();
-
+
public static ISourceEntityAccessor GetAccessor()
{
return (ISourceEntityAccessor)_accessors.GetOrAdd(typeof(T), t =>
{
- var typeName = $"{t.Namespace}.{t.Name}Accessor";
- if (t.IsGenericType)
- {
- var genericArgs = t.GetGenericArguments();
- var genericDef = t.GetGenericTypeDefinition();
- typeName = $"{genericDef.Namespace}.{genericDef.Name}Accessor`{genericArgs.Length}";
- }
-
- var type = Type.GetType(typeName)
- ?? Assembly.GetAssembly(t)?.GetType(typeName)
+ // 获取泛型类型定义信息(如果是泛型类型)
+ var isGeneric = t.IsGenericType;
+ var genericTypeDef = isGeneric ? t.GetGenericTypeDefinition() : null;
+ var arity = isGeneric ? genericTypeDef!.GetGenericArguments().Length : 0;
+
+ // 构建访问器类名
+ var typeName = isGeneric
+ ? $"{t.Namespace}.{genericTypeDef!.Name.Split('`')[0]}Accessor`{arity}"
+ : $"{t.Namespace}.{t.Name}Accessor";
+
+ // 尝试从当前程序集加载
+ var accessorType = Assembly.GetAssembly(t)!.GetType(typeName)
?? throw new InvalidOperationException($"Accessor type {typeName} not found");
-
- return t.IsGenericType
- ? Activator.CreateInstance(type.MakeGenericType(t.GetGenericArguments()))
- : Activator.CreateInstance(type);
+
+ // 处理泛型参数
+ if (isGeneric && accessorType.IsGenericTypeDefinition)
+ {
+ accessorType = accessorType.MakeGenericType(t.GetGenericArguments());
+ }
+
+ return Activator.CreateInstance(accessorType)!;
});
}
}
diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs
new file mode 100644
index 0000000..9c9c773
--- /dev/null
+++ b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs
@@ -0,0 +1,77 @@
+//
+#nullable enable
+using System;
+using System.Collections.Generic;
+using JiShe.CollectBus.Analyzers.Shared;
+namespace JiShe.CollectBus.IoTDB.Model;
+
+public sealed class TableModelSingleMeasuringEntityAccessor3 : ISourceEntityAccessor>
+{
+ public static string GetSingleColumn_Item1(global::JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity obj) => obj.SingleColumn.Item1;
+ public static void SetSingleColumn_Item1(global::JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity obj, string value) => obj.SingleColumn = (value, obj.SingleColumn.Item2);
+ public static T GetSingleColumn_Item2(global::JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity obj) => obj.SingleColumn.Item2;
+ public static void SetSingleColumn_Item2(global::JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity obj, T value) => obj.SingleColumn = (obj.SingleColumn.Item1, value);
+ public static string GetSystemName(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.SystemName;
+ public static void SetSystemName(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, string value) => obj.SystemName = value;
+ public static string GetProjectId(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.ProjectId;
+ public static void SetProjectId(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, string value) => obj.ProjectId = value;
+ public static string GetDeviceType(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.DeviceType;
+ public static void SetDeviceType(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, string value) => obj.DeviceType = value;
+ public static string GetDeviceId(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.DeviceId;
+ public static void SetDeviceId(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, string value) => obj.DeviceId = value;
+ public static long GetTimestamps(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.Timestamps;
+ public static void SetTimestamps(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, long value) => obj.Timestamps = value;
+ public List PropertyList { get; } = new List()
+ {
+"SingleColumn.Item1","SingleColumn.Item2","SystemName","ProjectId","DeviceType","DeviceId","Timestamps" };
+ public object GetPropertyValue(JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity targetEntity, string propertyName)
+ {
+ return propertyName switch
+ {
+ "SingleColumn.Item1" => GetSingleColumn_Item1(targetEntity),
+ "SingleColumn.Item2" => GetSingleColumn_Item2(targetEntity),
+ "SystemName" => GetSystemName(targetEntity),
+ "ProjectId" => GetProjectId(targetEntity),
+ "DeviceType" => GetDeviceType(targetEntity),
+ "DeviceId" => GetDeviceId(targetEntity),
+ "Timestamps" => GetTimestamps(targetEntity),
+ _ => throw new ArgumentException($"Unknown property: {propertyName}")
+ };
+ }
+ public void SetPropertyValue(JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity targetEntity, string propertyName, object value)
+ {
+ switch (propertyName)
+ {
+ case "SingleColumn.Item1":
+ SetSingleColumn_Item1(
+ targetEntity, (string)value);
+ break;
+ case "SingleColumn.Item2":
+ SetSingleColumn_Item2(
+ targetEntity, (T)value);
+ break;
+ case "SystemName":
+ SetSystemName(
+ targetEntity, (string)value);
+ break;
+ case "ProjectId":
+ SetProjectId(
+ targetEntity, (string)value);
+ break;
+ case "DeviceType":
+ SetDeviceType(
+ targetEntity, (string)value);
+ break;
+ case "DeviceId":
+ SetDeviceId(
+ targetEntity, (string)value);
+ break;
+ case "Timestamps":
+ SetTimestamps(
+ targetEntity, (long)value);
+ break;
+ default:
+ throw new ArgumentException($"Unknown property: {propertyName}");
+ }
+ }
+}
diff --git a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs
index aebce66..704363c 100644
--- a/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Provider/IoTDBProvider.cs
@@ -566,6 +566,8 @@ namespace JiShe.CollectBus.IoTDB.Provider
//metadata.ColumnNames.Insert(0, "Timestamps");
//metadata.DataTypes.Insert(0, TSDataType.TIMESTAMP);
+ var accessor = SourceEntityAccessorFactory.GetAccessor();
+
while (dataSet.HasNext() && results.Count < pageSize)
{
var record = dataSet.Next();
@@ -588,11 +590,14 @@ namespace JiShe.CollectBus.IoTDB.Provider
if (measurement.ToLower().EndsWith("time"))
{
- typeof(T).GetProperty(measurement)?.SetValue(entity, TimestampHelper.ConvertToDateTime(tempValue, TimestampUnit.Nanoseconds));
+ //typeof(T).GetProperty(measurement)?.SetValue(entity, TimestampHelper.ConvertToDateTime(tempValue, TimestampUnit.Nanoseconds));
+
+ accessor.SetPropertyValue(entity, measurement, TimestampHelper.ConvertToDateTime(tempValue, TimestampUnit.Nanoseconds));
}
else
{
- typeof(T).GetProperty(measurement)?.SetValue(entity, tempValue);
+ accessor.SetPropertyValue(entity, measurement, tempValue);
+ //typeof(T).GetProperty(measurement)?.SetValue(entity, tempValue);
}
}
From c47ee9446900e4f2c76baa3ec64fc522c6a35220 Mon Sep 17 00:00:00 2001
From: ChenYi <296215406@outlook.com>
Date: Wed, 7 May 2025 17:27:37 +0800
Subject: [PATCH 5/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ComplexTypeSourceAnalyzers.cs | 51 +++++++++++++++++--
...TableModelSingleMeasuringEntityAccessor.cs | 2 +-
.../ISourceEntityAccessor.cs | 8 ++-
3 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
index 195175a..ea0ef13 100644
--- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
+++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
@@ -157,6 +157,7 @@ namespace JiShe.CollectBus.IncrementalGenerator
code.AppendLine("// ");
code.AppendLine("#nullable enable");
code.AppendLine("using System;");
+ code.AppendLine("using System.Reflection;");
code.AppendLine("using System.Collections.Generic;");
code.AppendLine("using JiShe.CollectBus.Analyzers.Shared;");
code.AppendLine($"namespace {classSymbol.ContainingNamespace.ToDisplayString()};");
@@ -198,7 +199,14 @@ namespace JiShe.CollectBus.IncrementalGenerator
//生成当前类属性名称集合
GeneratePropertyListForSourceEntity(propList, code, compilation, classSymbol);
-
+
+ //生成当前类属性信息集合
+ GeneratePropertyInfoListForSourceEntity(
+ propList,
+ code,
+ compilation,
+ classSymbol);
+
//生成当前类属性访问
GetGeneratePropertyValueForSourceEntity(
@@ -213,9 +221,7 @@ namespace JiShe.CollectBus.IncrementalGenerator
code,
compilation,
classSymbol);
-
-
-
+
code.AppendLine("}");
return code.ToString();
}
@@ -468,5 +474,42 @@ namespace JiShe.CollectBus.IncrementalGenerator
code.AppendLine(" };");
}
+
+
+ ///
+ /// 生成当前类属性信息集合
+ ///
+ /// 属性集合
+ ///
+ ///
+ ///
+ private static void GeneratePropertyInfoListForSourceEntity(
+ IEnumerable propList,
+ StringBuilder code,
+ Compilation compilation,
+ INamedTypeSymbol classSymbol)
+ {
+ code.AppendLine(" public List PropertyList {get;} = new List()");
+ code.AppendLine(" {");
+ List tempPropList = new List();
+ foreach (var prop in propList)
+ {
+ if (prop.Type is INamedTypeSymbol { IsTupleType: true } tupleType)
+ {
+ foreach (var element in tupleType.TupleElements)
+ {
+ tempPropList.Add($"\"{prop.Name}.{element.Name}\"");
+ }
+ }
+ else
+ {
+ tempPropList.Add($"\"{prop.Name}\"");
+ }
+ }
+
+ code.Append(string.Join(",", tempPropList));
+
+ code.AppendLine(" };");
+ }
}
}
\ No newline at end of file
diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs
index 9c9c773..e0bedd4 100644
--- a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs
+++ b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs
@@ -21,7 +21,7 @@ public sealed class TableModelSingleMeasuringEntityAccessor3 : ISourceEntityA
public static void SetDeviceId(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, string value) => obj.DeviceId = value;
public static long GetTimestamps(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.Timestamps;
public static void SetTimestamps(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, long value) => obj.Timestamps = value;
- public List PropertyList { get; } = new List()
+ public List PropertyNameList { get; } = new List()
{
"SingleColumn.Item1","SingleColumn.Item2","SystemName","ProjectId","DeviceType","DeviceId","Timestamps" };
public object GetPropertyValue(JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity targetEntity, string propertyName)
diff --git a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
index baff180..5e67826 100644
--- a/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
+++ b/shared/JiShe.CollectBus.Analyzers.Shared/ISourceEntityAccessor.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
using System.Text;
namespace JiShe.CollectBus.Analyzers.Shared
@@ -25,6 +26,11 @@ namespace JiShe.CollectBus.Analyzers.Shared
///
/// 属性名称集合
///
- List PropertyList { get; }
+ List PropertyNameList { get; }
+
+ ///
+ /// 属性信息集合
+ ///
+ List PropertyInfoList { get; }
}
}
From f71ce3bacb65b20da327a280fcab856da8596d30 Mon Sep 17 00:00:00 2001
From: ChenYi <296215406@outlook.com>
Date: Thu, 8 May 2025 08:43:37 +0800
Subject: [PATCH 6/6] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=A2=9E=E9=87=8F?=
=?UTF-8?q?=E6=BA=90=E7=A0=81=E7=94=9F=E6=88=90=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ComplexTypeSourceAnalyzers.cs | 44 +++++++----
...TableModelSingleMeasuringEntityAccessor.cs | 77 -------------------
.../T37612012ProtocolPlugin.cs | 16 ++--
.../DataChannels/DataChannelManageService.cs | 14 ++--
.../BasicScheduledMeterReadingService.cs | 68 ++++++++--------
5 files changed, 78 insertions(+), 141 deletions(-)
delete mode 100644 modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs
diff --git a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
index ea0ef13..3b82bf2 100644
--- a/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
+++ b/modules/JiShe.CollectBus.Analyzers/ComplexTypeSourceAnalyzers.cs
@@ -452,7 +452,7 @@ namespace JiShe.CollectBus.IncrementalGenerator
Compilation compilation,
INamedTypeSymbol classSymbol)
{
- code.AppendLine(" public List PropertyList {get;} = new List()");
+ code.AppendLine(" public List PropertyNameList {get;} = new List()");
code.AppendLine(" {");
List tempPropList = new List();
foreach (var prop in propList)
@@ -477,39 +477,53 @@ namespace JiShe.CollectBus.IncrementalGenerator
///
- /// 生成当前类属性信息集合
+ /// 生成当前类属性信息集合(支持嵌套元组)
///
- /// 属性集合
- ///
- ///
- ///
private static void GeneratePropertyInfoListForSourceEntity(
IEnumerable propList,
StringBuilder code,
Compilation compilation,
INamedTypeSymbol classSymbol)
{
- code.AppendLine(" public List PropertyList {get;} = new List()");
+ code.AppendLine(" public List PropertyInfoList { get; } = new List");
code.AppendLine(" {");
- List tempPropList = new List();
+
+ var initializerLines = new List();
+
foreach (var prop in propList)
{
+ // 主属性
+ AddPropertyInitializer(classSymbol, prop, initializerLines);
+
+ // 处理元组嵌套属性
if (prop.Type is INamedTypeSymbol { IsTupleType: true } tupleType)
{
foreach (var element in tupleType.TupleElements)
{
- tempPropList.Add($"\"{prop.Name}.{element.Name}\"");
+ // 生成形如:typeof(ValueTuple).GetProperty("Item1")
+ var tupleTypeName = tupleType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ initializerLines.Add(
+ $"typeof({tupleTypeName}).GetProperty(\"{element.Name}\") ?? " +
+ $"throw new InvalidOperationException(\"Tuple element {element.Name} not found\")");
}
}
- else
- {
- tempPropList.Add($"\"{prop.Name}\"");
- }
}
- code.Append(string.Join(",", tempPropList));
-
+ code.AppendLine(string.Join(",\n", initializerLines));
code.AppendLine(" };");
}
+
+ private static void AddPropertyInitializer(
+ INamedTypeSymbol classSymbol,
+ IPropertySymbol prop,
+ List initializerLines)
+ {
+ var classType = classSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ initializerLines.Add(
+ $"typeof({classType}).GetProperty(\"{prop.Name}\", " +
+ "System.Reflection.BindingFlags.Public | " +
+ "System.Reflection.BindingFlags.Instance) ?? " +
+ $"throw new InvalidOperationException(\"Property {prop.Name} not found\")");
+ }
}
}
\ No newline at end of file
diff --git a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs b/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs
deleted file mode 100644
index e0bedd4..0000000
--- a/modules/JiShe.CollectBus.IoTDB/Model/TableModelSingleMeasuringEntityAccessor.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-//
-#nullable enable
-using System;
-using System.Collections.Generic;
-using JiShe.CollectBus.Analyzers.Shared;
-namespace JiShe.CollectBus.IoTDB.Model;
-
-public sealed class TableModelSingleMeasuringEntityAccessor3 : ISourceEntityAccessor>
-{
- public static string GetSingleColumn_Item1(global::JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity obj) => obj.SingleColumn.Item1;
- public static void SetSingleColumn_Item1(global::JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity obj, string value) => obj.SingleColumn = (value, obj.SingleColumn.Item2);
- public static T GetSingleColumn_Item2(global::JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity obj) => obj.SingleColumn.Item2;
- public static void SetSingleColumn_Item2(global::JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity obj, T value) => obj.SingleColumn = (obj.SingleColumn.Item1, value);
- public static string GetSystemName(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.SystemName;
- public static void SetSystemName(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, string value) => obj.SystemName = value;
- public static string GetProjectId(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.ProjectId;
- public static void SetProjectId(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, string value) => obj.ProjectId = value;
- public static string GetDeviceType(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.DeviceType;
- public static void SetDeviceType(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, string value) => obj.DeviceType = value;
- public static string GetDeviceId(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.DeviceId;
- public static void SetDeviceId(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, string value) => obj.DeviceId = value;
- public static long GetTimestamps(JiShe.CollectBus.IoTDB.Model.IoTEntity obj) => obj.Timestamps;
- public static void SetTimestamps(JiShe.CollectBus.IoTDB.Model.IoTEntity obj, long value) => obj.Timestamps = value;
- public List PropertyNameList { get; } = new List()
- {
-"SingleColumn.Item1","SingleColumn.Item2","SystemName","ProjectId","DeviceType","DeviceId","Timestamps" };
- public object GetPropertyValue(JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity targetEntity, string propertyName)
- {
- return propertyName switch
- {
- "SingleColumn.Item1" => GetSingleColumn_Item1(targetEntity),
- "SingleColumn.Item2" => GetSingleColumn_Item2(targetEntity),
- "SystemName" => GetSystemName(targetEntity),
- "ProjectId" => GetProjectId(targetEntity),
- "DeviceType" => GetDeviceType(targetEntity),
- "DeviceId" => GetDeviceId(targetEntity),
- "Timestamps" => GetTimestamps(targetEntity),
- _ => throw new ArgumentException($"Unknown property: {propertyName}")
- };
- }
- public void SetPropertyValue(JiShe.CollectBus.IoTDB.Model.TableModelSingleMeasuringEntity targetEntity, string propertyName, object value)
- {
- switch (propertyName)
- {
- case "SingleColumn.Item1":
- SetSingleColumn_Item1(
- targetEntity, (string)value);
- break;
- case "SingleColumn.Item2":
- SetSingleColumn_Item2(
- targetEntity, (T)value);
- break;
- case "SystemName":
- SetSystemName(
- targetEntity, (string)value);
- break;
- case "ProjectId":
- SetProjectId(
- targetEntity, (string)value);
- break;
- case "DeviceType":
- SetDeviceType(
- targetEntity, (string)value);
- break;
- case "DeviceId":
- SetDeviceId(
- targetEntity, (string)value);
- break;
- case "Timestamps":
- SetTimestamps(
- targetEntity, (long)value);
- break;
- default:
- throw new ArgumentException($"Unknown property: {propertyName}");
- }
- }
-}
diff --git a/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs b/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs
index a469147..73ecd15 100644
--- a/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs
+++ b/protocols/JiShe.CollectBus.Protocol.T37612012/T37612012ProtocolPlugin.cs
@@ -715,10 +715,10 @@ namespace JiShe.CollectBus.Protocol.T37612012
///
public virtual List Generate_DataUnit(DataTimeMark timeMark)
{
- List values = new List
- {
- SplitDataTime(timeMark.DataTime)//数据时间
- };
+ List values = new List();
+
+ values.AddRange(SplitDataTime(timeMark.DataTime));//数据时间
+
if (timeMark.Density > 0)
values.Add(timeMark.Density.HexToDecStr().PadLeft(2, '0'));//密度
if (timeMark.Point > 0)
@@ -727,13 +727,13 @@ namespace JiShe.CollectBus.Protocol.T37612012
}
- private string SplitDataTime(DateTime dataTime)
+ private List SplitDataTime(DateTime dataTime)
{
//2101060815
- List values = new List() { $"{dataTime}:YY", $"{dataTime}:MM", $"{dataTime}:dd", $"{dataTime}:HH", $"{dataTime}:mm", };
-
+ List values = new List() { $"{dataTime:yy}", $"{dataTime:MM}", $"{dataTime:dd}", $"{dataTime:HH}", $"{dataTime:mm}", };
values.Reverse();
- return string.Join("", values);
+ return values;
+ //return string.Join("", values);
}
#endregion
diff --git a/services/JiShe.CollectBus.Application/DataChannels/DataChannelManageService.cs b/services/JiShe.CollectBus.Application/DataChannels/DataChannelManageService.cs
index c129194..17ae182 100644
--- a/services/JiShe.CollectBus.Application/DataChannels/DataChannelManageService.cs
+++ b/services/JiShe.CollectBus.Application/DataChannels/DataChannelManageService.cs
@@ -125,13 +125,13 @@ namespace JiShe.CollectBus.DataChannels
// 批量写入数据库
await _dbProvider.BatchInsertAsync(metadata, records);
- // 限流推送Kafka
- await DeviceGroupBalanceControl.ProcessWithThrottleAsync(
- items: records,
- deviceIdSelector: data => data.DeviceId,
- processor: async (data, groupIndex) =>
- await KafkaProducerIssuedMessageAction(topicName, data, groupIndex)
- );
+ //// 限流推送Kafka
+ //await DeviceGroupBalanceControl.ProcessWithThrottleAsync(
+ // items: records,
+ // deviceIdSelector: data => data.DeviceId,
+ // processor: async (data, groupIndex) =>
+ // await KafkaProducerIssuedMessageAction(topicName, data, groupIndex)
+ //);
}
catch (Exception ex)
{
diff --git a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
index e75ad84..47b8a99 100644
--- a/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
+++ b/services/JiShe.CollectBus.Application/ScheduledMeterReading/BasicScheduledMeterReadingService.cs
@@ -336,47 +336,47 @@ namespace JiShe.CollectBus.ScheduledMeterReading
//此处代码不要删除
#if DEBUG
- //var timeDensity = "15";
- //var serverTagName = "JiSheCollectBus2";
- //var redisCacheMeterInfoHashKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoHashKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
- //var redisCacheMeterInfoSetIndexKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoSetIndexKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
- //var redisCacheMeterInfoZSetScoresIndexKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoZSetScoresIndexKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
+ var timeDensity = "15";
+ var serverTagName = "JiSheCollectBus2";
+ var redisCacheMeterInfoHashKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoHashKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
+ var redisCacheMeterInfoSetIndexKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoSetIndexKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
+ var redisCacheMeterInfoZSetScoresIndexKeyTemp = $"{string.Format(RedisConst.CacheMeterInfoZSetScoresIndexKey, SystemType, serverTagName, MeterTypeEnum.Ammeter, timeDensity)}";
List meterInfos = new List();
- //List focusAddressDataLista = new List();
- //var timer1 = Stopwatch.StartNew();
+ List focusAddressDataLista = new List();
+ var timer1 = Stopwatch.StartNew();
- //var allIds = new HashSet();
- //decimal? score = null;
- //string member = null;
+ var allIds = new HashSet();
+ decimal? score = null;
+ string member = null;
- //while (true)
- //{
- // var page = await _redisDataCacheService.GetAllPagedData(
- // redisCacheMeterInfoHashKeyTemp,
- // redisCacheMeterInfoZSetScoresIndexKeyTemp,
- // pageSize: 1000,
- // lastScore: score,
- // lastMember: member);
+ while (true)
+ {
+ var page = await _redisDataCacheService.GetAllPagedData(
+ redisCacheMeterInfoHashKeyTemp,
+ redisCacheMeterInfoZSetScoresIndexKeyTemp,
+ pageSize: 1000,
+ lastScore: score,
+ lastMember: member);
- // meterInfos.AddRange(page.Items);
- // focusAddressDataLista.AddRange(page.Items.Select(d => $"{d.MeterId}"));
- // foreach (var item in page.Items)
- // {
- // if (!allIds.Add(item.MemberId))
- // {
- // _logger.LogError($"{item.MemberId}Duplicate data found!");
- // }
- // }
- // if (!page.HasNext) break;
- // score = page.NextScore;
- // member = page.NextMember;
- //}
+ meterInfos.AddRange(page.Items);
+ focusAddressDataLista.AddRange(page.Items.Select(d => $"{d.MeterId}"));
+ foreach (var item in page.Items)
+ {
+ if (!allIds.Add(item.MemberId))
+ {
+ _logger.LogError($"{item.MemberId}Duplicate data found!");
+ }
+ }
+ if (!page.HasNext) break;
+ score = page.NextScore;
+ member = page.NextMember;
+ }
- //timer1.Stop();
- //_logger.LogError($"电表初始化读取数据总共花费时间{timer1.ElapsedMilliseconds}毫秒");
- //DeviceGroupBalanceControl.InitializeCache(focusAddressDataLista, _kafkaOptions.NumPartitions);
+ timer1.Stop();
+ _logger.LogError($"电表初始化读取数据总共花费时间{timer1.ElapsedMilliseconds}毫秒");
+ DeviceGroupBalanceControl.InitializeCache(focusAddressDataLista, _kafkaOptions.NumPartitions);
return;
#else
var meterInfos = await GetAmmeterInfoList(gatherCode);