diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/UnsTreeService.cs b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/UnsTreeService.cs index e14b495e..35913425 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/UnsTreeService.cs +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Uns/UnsTreeService.cs @@ -9,9 +9,9 @@ namespace ZB.MOM.WW.OtOpcUa.AdminUI.Uns; /// rows to the pure to nest into the browse tree. /// /// -/// A new context is created per call via the pooled factory — the same pattern every -/// AdminUI page uses — so the service is safe to register as a scoped singleton and call -/// concurrently from independent Blazor circuits. +/// Each call creates and disposes its own context via the pooled factory — the same pattern +/// every AdminUI page uses — so the service is safe to register as Scoped and used per +/// Blazor circuit. /// public sealed class UnsTreeService(IDbContextFactory dbFactory) : IUnsTreeService { @@ -55,11 +55,12 @@ public sealed class UnsTreeService(IDbContextFactory dbF .ToListAsync(ct)) .ToDictionary(x => x.EquipmentId, x => x.Count, StringComparer.Ordinal); - // Per-equipment virtual-tag counts (EquipmentId is always set on virtual tags). + // Per-equipment virtual-tag counts (virtual tags with no equipment are excluded). var vtagCounts = (await db.VirtualTags .AsNoTracking() + .Where(v => v.EquipmentId != null) .GroupBy(v => v.EquipmentId) - .Select(g => new { EquipmentId = g.Key, Count = g.Count() }) + .Select(g => new { EquipmentId = g.Key!, Count = g.Count() }) .ToListAsync(ct)) .ToDictionary(x => x.EquipmentId, x => x.Count, StringComparer.Ordinal);