From 6b21c387d50bfa3ac087d8e317080089b7279191 Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Thu, 17 Jul 2025 17:28:12 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0MQTT=E5=85=B3=E8=81=94?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E7=9A=84=E5=88=AB=E5=90=8D=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E4=BA=86=EF=BC=8C=E5=90=8C=E4=B8=AA?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=8F=91=E7=BB=99=E4=B8=8D=E5=90=8C=E7=9A=84?= =?UTF-8?q?MQTT=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=9A=84=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E4=B8=8D=E5=90=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.xaml.cs | 4 +- Data/Entities/DbMqtt.cs | 4 +- Data/Entities/DbVariableData.cs | 4 +- Data/Entities/DbVariableDataMqtt.cs | 19 --- Data/Repositories/MqttRepository.cs | 12 +- Data/Repositories/VarDataRepository.cs | 183 ++++++++++++++++-------- Models/Mqtt.cs | 2 +- Models/VariableData.cs | 2 +- Profiles/MappingProfile.cs | 1 + Services/DialogService.cs | 24 ++++ Services/IDialogService.cs | 2 + ViewModels/MqttServerDetailViewModel.cs | 23 +-- ViewModels/VariableTableViewModel.cs | 75 +++++++--- Views/MqttServerDetailView.xaml | 13 +- 14 files changed, 238 insertions(+), 130 deletions(-) delete mode 100644 Data/Entities/DbVariableDataMqtt.cs diff --git a/App.xaml.cs b/App.xaml.cs index 0686e82..6edc193 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -126,6 +126,7 @@ public partial class App : Application services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); // 注册视图模型 services.AddSingleton(); services.AddSingleton(); @@ -251,7 +252,8 @@ public partial class App : Application _db.CodeFirst.InitTables(); _db.CodeFirst.InitTables(); _db.CodeFirst.InitTables(); - _db.CodeFirst.InitTables(); + _db.CodeFirst.InitTables(); + // _db.CodeFirst.InitTables(); _db.CodeFirst.InitTables(); } } \ No newline at end of file diff --git a/Data/Entities/DbMqtt.cs b/Data/Entities/DbMqtt.cs index c124d93..0bc43d6 100644 --- a/Data/Entities/DbMqtt.cs +++ b/Data/Entities/DbMqtt.cs @@ -90,6 +90,6 @@ public class DbMqtt /// /// 关联的变量数据列表。 /// - [Navigate(typeof(DbVariableDataMqtt), "MqttId", "VariableDataId")] - public List? VariableDatas { get; set; } + [Navigate(NavigateType.OneToMany, nameof(DbVariableMqtt.MqttId))] + public List? VariableMqtts { get; set; } } \ No newline at end of file diff --git a/Data/Entities/DbVariableData.cs b/Data/Entities/DbVariableData.cs index 81b4c72..52b76f3 100644 --- a/Data/Entities/DbVariableData.cs +++ b/Data/Entities/DbVariableData.cs @@ -161,8 +161,8 @@ public class DbVariableData /// /// 关联的MQTT配置列表。 /// - [Navigate(typeof(DbVariableDataMqtt), "VariableDataId", "MqttId")] - public List? Mqtts { get; set; } + [Navigate(NavigateType.OneToMany, nameof(DbVariableMqtt.VariableDataId))] + public List? VariableMqtts { get; set; } /// /// 关联的历史记录列表。 diff --git a/Data/Entities/DbVariableDataMqtt.cs b/Data/Entities/DbVariableDataMqtt.cs deleted file mode 100644 index 9f0b9bc..0000000 --- a/Data/Entities/DbVariableDataMqtt.cs +++ /dev/null @@ -1,19 +0,0 @@ -using SqlSugar; - -namespace PMSWPF.Data.Entities; - -[SugarTable("VariableDataMqtt")] -public class DbVariableDataMqtt -{ - [SugarColumn(IsPrimaryKey = true)] - public int VariableDataId { get; set; } - - [SugarColumn(IsPrimaryKey = true)] - public int MqttId { get; set; } - - [Navigate(NavigateType.ManyToOne, nameof(VariableDataId))] - public DbVariableData VariableData { get; set; } - - [Navigate(NavigateType.ManyToOne, nameof(MqttId))] - public DbMqtt Mqtt { get; set; } -} \ No newline at end of file diff --git a/Data/Repositories/MqttRepository.cs b/Data/Repositories/MqttRepository.cs index 4b539ee..1851e6b 100644 --- a/Data/Repositories/MqttRepository.cs +++ b/Data/Repositories/MqttRepository.cs @@ -52,7 +52,9 @@ public class MqttRepository stopwatch.Start(); using (var _db = DbContext.GetInstance()) { - var result = await _db.Queryable().Includes(m=>m.VariableDatas) + var result = await _db.Queryable() + .Includes(m => m.VariableMqtts, vm => vm.VariableData) + .Includes(m => m.VariableMqtts, vm => vm.Mqtt) .ToListAsync(); stopwatch.Stop(); NlogHelper.Info($"获取所有Mqtt配置耗时:{stopwatch.ElapsedMilliseconds}ms"); @@ -95,7 +97,7 @@ public class MqttRepository catch (Exception ex) { await db.RollbackTranAsync(); - NlogHelper.Error( $"添加MQTT配置 {{mqtt.Name}} 失败",ex); + NlogHelper.Error($"添加MQTT配置 {{mqtt.Name}} 失败", ex); throw; } } @@ -157,11 +159,11 @@ public class MqttRepository .ExecuteCommandAsync(); // DeleteAsync menu entry var menu = await _menuRepository.GetMenuByDataIdAsync(mqtt.Id, MenuType.MqttMenu); - if (menu!=null ) + if (menu != null) { await _menuRepository.DeleteAsync(menu, db); } - + await db.CommitTranAsync(); stopwatch.Stop(); NlogHelper.Info($"删除Mqtt配置ID '{mqtt.Id}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); @@ -170,7 +172,7 @@ public class MqttRepository catch (Exception ex) { await db.RollbackTranAsync(); - NlogHelper.Error( $"删除MQTT配置 {{mqtt.Name}} 失败",ex); + NlogHelper.Error($"删除MQTT配置 {{mqtt.Name}} 失败", ex); throw; } } diff --git a/Data/Repositories/VarDataRepository.cs b/Data/Repositories/VarDataRepository.cs index 911c4d1..850bfe2 100644 --- a/Data/Repositories/VarDataRepository.cs +++ b/Data/Repositories/VarDataRepository.cs @@ -31,17 +31,28 @@ public class VarDataRepository { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - using (var _db = DbContext.GetInstance()) + using (var db = DbContext.GetInstance()) { - var result = await _db.Queryable() - .In(id) - .SingleAsync(); + var result = await GetByIdAsync(id, db); stopwatch.Stop(); NlogHelper.Info($"根据ID '{id}' 获取VariableData耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } } + /// + /// 根据ID获取VariableData + /// + /// 主键ID + /// SqlSugarClient实例 + /// + public async Task GetByIdAsync(int id, SqlSugarClient db) + { + return await db.Queryable() + .In(id) + .SingleAsync(); + } + /// /// 获取所有VariableData /// @@ -50,19 +61,30 @@ public class VarDataRepository { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - using (var _db = DbContext.GetInstance()) + using (var db = DbContext.GetInstance()) { - var result = await _db.Queryable() - .Includes(d => d.VariableTable) - .Includes(d => d.VariableTable.Device) - .ToListAsync(); + var result = await GetAllAsync(db); stopwatch.Stop(); NlogHelper.Info($"获取所有VariableData耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result.Select(d => _mapper.Map(d)) - .ToList(); + return result; } } + /// + /// 获取所有VariableData + /// + /// SqlSugarClient实例 + /// + public async Task> GetAllAsync(SqlSugarClient db) + { + var result = await db.Queryable() + .Includes(d => d.VariableTable) + .Includes(d => d.VariableTable.Device) + .ToListAsync(); + return result.Select(d => _mapper.Map(d)) + .ToList(); + } + /// /// 获取所有VariableData /// @@ -71,17 +93,29 @@ public class VarDataRepository { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - using (var _db = DbContext.GetInstance()) + using (var db = DbContext.GetInstance()) { - var result = await _db.Queryable() - .Where(d => d.VariableTableId == varTableId) - .ToListAsync(); + var result = await GetByVariableTableIdAsync(varTableId, db); stopwatch.Stop(); NlogHelper.Info($"获取变量表的所有变量{result.Count()}个耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result.Select(d=>_mapper.Map(d)).ToList(); + return result; } } + /// + /// 获取所有VariableData + /// + /// SqlSugarClient实例 + /// + public async Task> GetByVariableTableIdAsync(int varTableId, SqlSugarClient db) + { + var result = await db.Queryable() + .Where(d => d.VariableTableId == varTableId) + .ToListAsync(); + return result.Select(d => _mapper.Map(d)) + .ToList(); + } + /// /// 新增VariableData /// @@ -170,16 +204,28 @@ public class VarDataRepository { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - using (var _db = DbContext.GetInstance()) + using (var db = DbContext.GetInstance()) { - var result = await _db.Updateable(_mapper.Map(variableData)) - .ExecuteCommandAsync(); + var result = await UpdateAsync(variableData, db); stopwatch.Stop(); NlogHelper.Info($"更新VariableData '{variableData.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } } + /// + /// 更新VariableData + /// + /// VariableData实体 + /// SqlSugarClient实例 + /// + public async Task UpdateAsync(VariableData variableData, SqlSugarClient db) + { + var result = await db.Updateable(_mapper.Map(variableData)) + .ExecuteCommandAsync(); + return result; + } + /// /// 更新VariableData /// @@ -188,7 +234,7 @@ public class VarDataRepository public async Task UpdateAsync(List variableDatas) { using var _db = DbContext.GetInstance(); - return await UpdateAsync(variableDatas, _db); + return await UpdateAsync(variableDatas, _db); } /// @@ -230,18 +276,13 @@ public class VarDataRepository /// 根据ID删除VariableData /// /// 主键ID + /// SqlSugarClient实例 /// public async Task DeleteAsync(VariableData variableData, SqlSugarClient db) { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - using var _db = DbContext.GetInstance(); - - var result = await _db.Deleteable() - .Where(d => d.Id == variableData.Id) - .ExecuteCommandAsync(); - stopwatch.Stop(); - NlogHelper.Info($"删除VariableData: '{variableData.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + var result = await db.Deleteable() + .Where(d => d.Id == variableData.Id) + .ExecuteCommandAsync(); return result; } @@ -267,58 +308,78 @@ public class VarDataRepository /// 删除VariableData /// /// 主键ID + /// SqlSugarClient实例 /// public async Task DeleteAsync(IEnumerable variableDatas, SqlSugarClient db) { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - using var _db = DbContext.GetInstance(); - var dbList = variableDatas.Select(vd => _mapper.Map(vd)) .ToList(); - var result = await _db.Deleteable(dbList) - .ExecuteCommandAsync(); - stopwatch.Stop(); - NlogHelper.Info($"删除VariableData: '{variableDatas.Count()}'个 耗时:{stopwatch.ElapsedMilliseconds}ms"); + var result = await db.Deleteable(dbList) + .ExecuteCommandAsync(); return result; } + // public VarDataRepository(IMapper mapper) + // { + // _mapper = mapper; + // } + /// - /// 为变量添加MQTT服务器关联。 + /// 为变量添加MQTT服务器关联,并指定别名。 /// + /// /// 要添加MQTT服务器的变量数据列表。 - /// 要关联的MQTT服务器。 - /// 成功添加关联的数量。 - public async Task AddMqttToVariablesAsync(IEnumerable variableDatas, Mqtt mqtt) + /// 成功添加或更新关联的数量。 + public async Task AddMqttToVariablesAsync(IEnumerable variableMqttList) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - int addedCount = 0; + int affectedCount = 0; + using var db = DbContext.GetInstance(); + //插入列表 + List insertDbVM = new List(); - using (var db = DbContext.GetInstance()) + foreach (var variableMqtt in variableMqttList) { - foreach (var variableData in variableDatas) + var existingAlias = await db.Queryable() + .Where(it => it.VariableDataId == variableMqtt.VariableData.Id && it.MqttId == variableMqtt.Mqtt.Id) + .FirstAsync(); + if (existingAlias == null) { - // 检查是否已存在该关联 - var existingAssociation = await db.Queryable() - .Where(x => x.VariableDataId == variableData.Id && x.MqttId == mqtt.Id) - .FirstAsync(); - - if (existingAssociation == null) - { - // 如果不存在,则添加新的关联 - await db.Insertable(new DbVariableDataMqtt - { - VariableDataId = variableData.Id, - MqttId = mqtt.Id - }).ExecuteCommandAsync(); - addedCount++; - } + // 如果不存在,则添加新的关联 + insertDbVM.Add(new DbVariableMqtt + { + VariableDataId = variableMqtt.VariableData.Id, + MqttId = variableMqtt.Mqtt.Id, + MqttAlias = variableMqtt.MqttAlias, + CreateTime = DateTime.Now, + UpdateTime = DateTime.Now + }); + + affectedCount++; + } + else if (existingAlias.MqttAlias !=variableMqtt.MqttAlias) + { + // 如果存在但别名不同,则更新别名 + await db.Updateable() + .SetColumns(it => it.MqttAlias == variableMqtt.MqttAlias) + .Where(it => it.VariableDataId == variableMqtt.VariableData.Id && it.MqttId == variableMqtt.Mqtt.Id) + .ExecuteCommandAsync(); + NlogHelper.Info( + $"为 {variableMqtt.VariableData.Name} 变量更新MQTT服务器{variableMqtt.Mqtt.Name}关联."); + affectedCount++; } } + if (insertDbVM.Count > 0) + { + await db.Insertable(insertDbVM).ExecuteCommandAsync(); + NlogHelper.Info( + $"为 {insertDbVM.Count} 个变量添加MQTT服务器 关联,成功影响 {affectedCount} 个,耗时:{stopwatch.ElapsedMilliseconds}ms"); + } + stopwatch.Stop(); - NlogHelper.Info($"为 {variableDatas.Count()} 个变量添加MQTT服务器 '{mqtt.Name}' 关联,成功添加 {addedCount} 个,耗时:{stopwatch.ElapsedMilliseconds}ms"); - return addedCount; + + return affectedCount; } } \ No newline at end of file diff --git a/Models/Mqtt.cs b/Models/Mqtt.cs index fca9d27..c5f44c8 100644 --- a/Models/Mqtt.cs +++ b/Models/Mqtt.cs @@ -95,7 +95,7 @@ public partial class Mqtt : ObservableObject /// /// 关联的变量数据列表。 /// - public List? VariableDatas { get; set; } + public List? VariableMqtts { get; set; } /// /// 是否连接。 diff --git a/Models/VariableData.cs b/Models/VariableData.cs index f5b6dff..bfbfbb5 100644 --- a/Models/VariableData.cs +++ b/Models/VariableData.cs @@ -175,7 +175,7 @@ public partial class VariableData : ObservableObject, IEquatable /// /// 关联的MQTT配置列表。 /// - public List Mqtts { get; set; } + public List? VariableMqtts { get; set; } partial void OnPollLevelTypeChanged(PollLevelType value) { diff --git a/Profiles/MappingProfile.cs b/Profiles/MappingProfile.cs index 10aa32b..b01db1f 100644 --- a/Profiles/MappingProfile.cs +++ b/Profiles/MappingProfile.cs @@ -25,6 +25,7 @@ public class MappingProfile : Profile CreateMap().ReverseMap(); // --- MQTT 和 变量数据 映射 --- CreateMap().ReverseMap(); + CreateMap().ReverseMap(); CreateMap().ReverseMap(); diff --git a/Services/DialogService.cs b/Services/DialogService.cs index 5378aaa..360f540 100644 --- a/Services/DialogService.cs +++ b/Services/DialogService.cs @@ -237,4 +237,28 @@ public class DialogService :IDialogService var dialog = new ImportResultDialog(vm); await dialog.ShowAsync(); } + + public async Task ShowMqttAliasDialog(string variableName, string mqttServerName) + { + var vm = new MqttAliasDialogViewModel(variableName, mqttServerName); + var dialog = new MqttAliasDialog(vm); + var result = await dialog.ShowAsync(); + if (result == ContentDialogResult.Primary) + { + return vm.MqttAlias; + } + return null; + } + + public async Task> ShowMqttAliasBatchEditDialog(List selectedVariables, Mqtt selectedMqtt) + { + var vm = new MqttAliasBatchEditDialogViewModel(selectedVariables, selectedMqtt); + var dialog = new MqttAliasBatchEditDialog(vm); + var result = await dialog.ShowAsync(); + if (result == ContentDialogResult.Primary) + { + return vm.VariablesToEdit.ToList(); + } + return null; + } } \ No newline at end of file diff --git a/Services/IDialogService.cs b/Services/IDialogService.cs index 1ea5fc5..424f689 100644 --- a/Services/IDialogService.cs +++ b/Services/IDialogService.cs @@ -27,4 +27,6 @@ public interface IDialogService Task ShowOpcUaUpdateTypeDialog(); Task ShowIsActiveDialog(bool currentIsActive); Task ShowImportResultDialog(List importedVariables, List existingVariables); + Task ShowMqttAliasDialog(string variableName, string mqttServerName); + Task> ShowMqttAliasBatchEditDialog(List selectedVariables, Mqtt selectedMqtt); } \ No newline at end of file diff --git a/ViewModels/MqttServerDetailViewModel.cs b/ViewModels/MqttServerDetailViewModel.cs index 8504bab..2ca2d5f 100644 --- a/ViewModels/MqttServerDetailViewModel.cs +++ b/ViewModels/MqttServerDetailViewModel.cs @@ -9,6 +9,7 @@ using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using System.Collections.Generic; +using PMSWPF.Data.Repositories; namespace PMSWPF.ViewModels { @@ -32,7 +33,9 @@ namespace PMSWPF.ViewModels /// 与当前MQTT服务器关联的变量数据集合。 /// [ObservableProperty] - private ObservableCollection _associatedVariables; + private ObservableCollection _associatedVariables; + + private readonly VariableMqttAliasRepository _variableMqttAliasRepository; /// /// 构造函数。 @@ -41,19 +44,19 @@ namespace PMSWPF.ViewModels /// 数据服务。 /// 对话框服务。 public MqttServerDetailViewModel(ILogger logger, DataServices dataServices, - IDialogService dialogService) + IDialogService dialogService, VariableMqttAliasRepository variableMqttAliasRepository) { _logger = logger; _dataServices = dataServices; _dialogService = dialogService; - AssociatedVariables = new ObservableCollection(); + _variableMqttAliasRepository = variableMqttAliasRepository; } public override void OnLoaded() { - if (CurrentMqtt.VariableDatas != null) + if (CurrentMqtt.VariableMqtts != null) { - AssociatedVariables = new ObservableCollection(CurrentMqtt.VariableDatas); + AssociatedVariables =new ObservableCollection(CurrentMqtt.VariableMqtts) ; } } @@ -108,11 +111,11 @@ namespace PMSWPF.ViewModels foreach (var variable in variablesList) // 使用ToList()避免在迭代时修改集合 { // 移除变量与当前MQTT服务器的关联 - variable.Mqtts?.Remove(CurrentMqtt); - // 标记变量为已修改,以便保存时更新数据库 - variable.IsModified = true; - AssociatedVariables.Remove(variable); - _logger.LogInformation($"Removed variable {variable.Name} from MQTT server {CurrentMqtt.Name}."); + // variable.Mqtts?.Remove(CurrentMqtt); + // // 标记变量为已修改,以便保存时更新数据库 + // variable.IsModified = true; + // AssociatedVariables.Remove(variable); + // _logger.LogInformation($"Removed variable {variable.Name} from MQTT server {CurrentMqtt.Name}."); } // TODO: 这里需要调用DataServices来更新数据库中VariableData的Mqtt关联 diff --git a/ViewModels/VariableTableViewModel.cs b/ViewModels/VariableTableViewModel.cs index f49b964..7471436 100644 --- a/ViewModels/VariableTableViewModel.cs +++ b/ViewModels/VariableTableViewModel.cs @@ -13,6 +13,7 @@ using PMSWPF.Extensions; using PMSWPF.Helper; using PMSWPF.Models; using PMSWPF.Services; +using SqlSugar; namespace PMSWPF.ViewModels; @@ -520,6 +521,7 @@ partial class VariableTableViewModel : ViewModelBase // 使用 AutoMapper 更新现有对象的属性,保持对象引用不变 _mapper.Map(newVariable, currentVariable); } + // 从字典中移除已处理的项,剩余的将是新增项 latestVariablesDict.Remove(currentVariable.Id); } @@ -582,7 +584,8 @@ partial class VariableTableViewModel : ViewModelBase // 根据协议类型检查S7地址或NodeId是否重复 if (variableTable.ProtocolType == ProtocolType.S7) { - if (!string.IsNullOrEmpty(varData.S7Address) && DataVariables.Any(v => v.S7Address == varData.S7Address)) + if (!string.IsNullOrEmpty(varData.S7Address) && + DataVariables.Any(v => v.S7Address == varData.S7Address)) { isDuplicate = true; duplicateReason = $"S7地址 '{varData.S7Address}' 已存在。"; @@ -774,41 +777,69 @@ partial class VariableTableViewModel : ViewModelBase return; // 用户取消选择 } - // 调用新的仓库方法来添加MQTT服务器关联 - var addedCount = await _varDataRepository.AddMqttToVariablesAsync(validVariables, selectedMqtt); + // 显示批量编辑别名对话框 + var editedVariableMqtts = await _dialogService.ShowMqttAliasBatchEditDialog(validVariables, selectedMqtt); - if (addedCount > 0) + if (editedVariableMqtts == null || !editedVariableMqtts.Any()) { - // 更新已经加载的变量的Mqtt服务器和Mqtt服务器的变量表 - foreach (var variable in validVariables) - { - // 更新变量的 Mqtts 集合 - if (variable.Mqtts == null) + NotificationHelper.ShowInfo("没有变量别名被设置或已取消。"); + return; + } + + + int totalAffectedCount = 0; + // 调用仓库方法来添加或更新MQTT服务器关联和别名 + var affectedCount = await _varDataRepository.AddMqttToVariablesAsync(editedVariableMqtts); + totalAffectedCount += affectedCount; + if (affectedCount == 0) + { + NotificationHelper.ShowInfo("没有任何要添加或者更新的MQTT服务器."); + return; + } + + foreach (var editedVariableMqtt in editedVariableMqtts) + { + + // 更新内存中的 VariableData 对象 + var originalVariable = editedVariableMqtt.VariableData; + if (originalVariable.VariableMqtts == null) { - variable.Mqtts = new List(); - } - if (!variable.Mqtts.Any(m => m.Id == selectedMqtt.Id)) - { - variable.Mqtts.Add(selectedMqtt); + originalVariable.VariableMqtts = new List(); } - // 更新 Mqtt 服务器的 VariableDatas 集合 - if (selectedMqtt.VariableDatas == null) + // 检查是否已存在该变量与该MQTT服务器的关联 + var existingVariableMqtt + = originalVariable.VariableMqtts.FirstOrDefault(vm => vm.MqttId == + editedVariableMqtt.Mqtt.Id); + + if (existingVariableMqtt == null) { - selectedMqtt.VariableDatas = new List(); + // 如果不存在,则添加新的关联 + originalVariable.VariableMqtts.Add(new VariableMqtt + { + VariableDataId = originalVariable.Id, + MqttId = editedVariableMqtt.Mqtt.Id, + MqttAlias = editedVariableMqtt.MqttAlias, + Mqtt = editedVariableMqtt.Mqtt // 关联Mqtt对象,方便UI显示 + }); } - if (!selectedMqtt.VariableDatas.Any(v => v.Id == variable.Id)) + else { - selectedMqtt.VariableDatas.Add(variable); + // 如果存在,则更新别名 + existingVariableMqtt.MqttAlias = editedVariableMqtt.MqttAlias; } - } + } + + + if (totalAffectedCount > 0) + { // 刷新界面以反映更改 await RefreshDataView(); - NotificationHelper.ShowSuccess($"已成功为 {addedCount} 个变量添加MQTT服务器: {selectedMqtt.Name}"); + NotificationHelper.ShowSuccess($"已成功为 {totalAffectedCount} 个变量添加/更新MQTT服务器: {selectedMqtt.Name} 的别名。"); } else { - NotificationHelper.ShowInfo($"没有新的变量关联到MQTT服务器: {selectedMqtt.Name},可能已存在。"); + NotificationHelper.ShowInfo($"没有新的变量关联或别名更新到MQTT服务器: {selectedMqtt.Name}。"); } } catch (Exception ex) diff --git a/Views/MqttServerDetailView.xaml b/Views/MqttServerDetailView.xaml index 8318c2b..a909b8c 100644 --- a/Views/MqttServerDetailView.xaml +++ b/Views/MqttServerDetailView.xaml @@ -90,12 +90,13 @@ IsReadOnly="True" SelectionMode="Extended"> - - - - - - + + + + + + +