diff --git a/DMS.Infrastructure.UnitTests/DMS.Infrastructure.UnitTests.csproj b/DMS.Infrastructure.UnitTests/DMS.Infrastructure.UnitTests.csproj new file mode 100644 index 0000000..22fefae --- /dev/null +++ b/DMS.Infrastructure.UnitTests/DMS.Infrastructure.UnitTests.csproj @@ -0,0 +1,29 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + + diff --git a/DMS.Infrastructure.UnitTests/ExampleTest.cs b/DMS.Infrastructure.UnitTests/ExampleTest.cs new file mode 100644 index 0000000..7422db1 --- /dev/null +++ b/DMS.Infrastructure.UnitTests/ExampleTest.cs @@ -0,0 +1,18 @@ +using Xunit; + +namespace DMS.Infrastructure.UnitTests +{ + public class VariableTableRepositoryTests + { + public VariableTableRepositoryTests() + { + + } + + [Fact] + public void AddAsync() + { + Assert.True(true); + } + } +} \ No newline at end of file diff --git a/DMS.Infrastructure.UnitTests/FakerHelper.cs b/DMS.Infrastructure.UnitTests/FakerHelper.cs new file mode 100644 index 0000000..229ddb5 --- /dev/null +++ b/DMS.Infrastructure.UnitTests/FakerHelper.cs @@ -0,0 +1,59 @@ +using Bogus; +using DMS.Infrastructure.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DMS.Infrastructure.UnitTests +{ + public static class FakerHelper + { + public static DbDevice FakeDbDevice() + { + var dbDevice = new Faker() + .RuleFor(d => d.Name, f => f.Commerce.ProductName()) + .RuleFor(d => d.Description, f => f.Commerce.ProductDescription()) + .RuleFor(d => d.Ip, f => f.Internet.Ip()) + .Generate(); + dbDevice.Prot = 102; + dbDevice.ProtocolType = Core.Enums.ProtocolType.S7; + dbDevice.Slot = 1; + dbDevice.Rack = 0; + dbDevice.CpuType = S7.Net.CpuType.S71200; + dbDevice.DeviceType = Core.Enums.DeviceType.SiemensPLC; + + + return dbDevice; + } + + public static DbVariableTable FakeDbVariableTable() + { + var dbVarTable = new Faker() + .RuleFor(d => d.Name, f => f.Commerce.ProductName()) + .RuleFor(d => d.Description, f => f.Commerce.ProductDescription()) + .Generate(); + dbVarTable.ProtocolType = Core.Enums.ProtocolType.S7; + dbVarTable.IsActive=true; + return dbVarTable; + } + + public static DbVariable FakeDbVariable() + { + var dbVariable = new Faker() + .RuleFor(d => d.Name, f => f.Commerce.ProductName()) + .RuleFor(d => d.Description, f => f.Commerce.ProductDescription()) + .RuleFor(d => d.S7Address, f => f.Internet.DomainWord()) + .RuleFor(d => d.DataValue, f => f.Commerce.Price()) + .Generate(); + dbVariable.ProtocolType = Core.Enums.ProtocolType.S7; + dbVariable.IsActive = true; + dbVariable.SignalType=Core.Enums.SignalType.RunSignal; + dbVariable.UpdateTime=DateTime.Now; + dbVariable.DataType = "String"; + return dbVariable; + } + + } +} diff --git a/DMS.Infrastructure.UnitTests/Repository_Test/BaseRepositoryTests.cs b/DMS.Infrastructure.UnitTests/Repository_Test/BaseRepositoryTests.cs new file mode 100644 index 0000000..a1b9c2b --- /dev/null +++ b/DMS.Infrastructure.UnitTests/Repository_Test/BaseRepositoryTests.cs @@ -0,0 +1,28 @@ +using DMS.Infrastructure.Data; +using DMS.Infrastructure.Repositories; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DMS.Infrastructure.UnitTests.Repository_Test +{ + public class BaseRepositoryTests + { + + protected readonly SqlSugarDbContext _sqlSugarDbContext; + + public BaseRepositoryTests() + { + // Load real connection settings + var connectionSettings = new Config.ConnectionSettings() + { + Database = "DMS_test" + }; + _sqlSugarDbContext = new SqlSugarDbContext(connectionSettings); + _sqlSugarDbContext.GetInstance().DbMaintenance.CreateDatabase(); + _sqlSugarDbContext.GetInstance().CodeFirst.InitTables(); + } + } +} diff --git a/DMS.Infrastructure.UnitTests/Repository_Test/DeviceRepositoryTests.cs b/DMS.Infrastructure.UnitTests/Repository_Test/DeviceRepositoryTests.cs new file mode 100644 index 0000000..61c4d33 --- /dev/null +++ b/DMS.Infrastructure.UnitTests/Repository_Test/DeviceRepositoryTests.cs @@ -0,0 +1,54 @@ +using Xunit; +using Moq; +using AutoMapper; +using DMS.Infrastructure.Data; +using DMS.Infrastructure.Entities; +using DMS.Infrastructure.Repositories; +using SqlSugar; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace DMS.Infrastructure.UnitTests.Repository_Test +{ + public class DeviceRepositoryTests:BaseRepositoryTests + { + private readonly DeviceRepository _deviceRepository; + + public DeviceRepositoryTests() : base() + { + + _deviceRepository = new DeviceRepository(_sqlSugarDbContext); + } + + [Fact] + public async Task GetAllAsync_ShouldReturnListOfDbDevices() + { + + // Act + var result = await _deviceRepository.GetAllAsync(); + + // Assert + Assert.NotNull(result); + } + [Fact] + public async Task AddAsync_Test() + { + for (var i = 0; i < 10; i++) + { + var dbDevice = FakerHelper.FakeDbDevice(); + //await _sqlSugarDbContext.GetInstance().Insertable(dbDevice).ExecuteCommandAsync(); + + // Act + var result = await _deviceRepository.AddAsync(dbDevice); + } + + // Assert + //Assert.NotNull(result); + //Assert.Contains(result, d => d.Name == testDevice.Name); + + // Clean up after the test + //await _sqlSugarDbContext.GetInstance().Deleteable().ExecuteCommandAsync(); + } + } +} \ No newline at end of file diff --git a/DMS.Infrastructure.UnitTests/Repository_Test/VariableTableRepositoryTests.cs b/DMS.Infrastructure.UnitTests/Repository_Test/VariableTableRepositoryTests.cs new file mode 100644 index 0000000..e070039 --- /dev/null +++ b/DMS.Infrastructure.UnitTests/Repository_Test/VariableTableRepositoryTests.cs @@ -0,0 +1,13 @@ +using Xunit; + +namespace DMS.Infrastructure.UnitTests.Repository_Test +{ + public class VariableTableRepositoryTests + { + [Fact] + public void Test1() + { + Assert.True(true); + } + } +} \ No newline at end of file diff --git a/DMS.Infrastructure/Interfaces/IDeviceRepository.cs b/DMS.Infrastructure/Interfaces/IDeviceRepository.cs index eee16e6..3ab30b3 100644 --- a/DMS.Infrastructure/Interfaces/IDeviceRepository.cs +++ b/DMS.Infrastructure/Interfaces/IDeviceRepository.cs @@ -1,5 +1,4 @@ using DMS.Core.Models; -using DMS.Core.Enums; using System.Collections.Generic; using System.Threading.Tasks; @@ -7,12 +6,10 @@ namespace DMS.Infrastructure.Interfaces { public interface IDeviceRepository { - Task UpdateAsync(Device device); - + Task AddAsync(Device model); + Task UpdateAsync(Device model); + Task DeleteAsync(Device model); Task> GetAllAsync(); Task GetByIdAsync(int id); - Task DeleteAsync(Device device, List menus); - - Task AddAsync(Device device); } } \ No newline at end of file diff --git a/DMS.Infrastructure/Interfaces/IDeviceService.cs b/DMS.Infrastructure/Interfaces/IDeviceService.cs new file mode 100644 index 0000000..4fbfd97 --- /dev/null +++ b/DMS.Infrastructure/Interfaces/IDeviceService.cs @@ -0,0 +1,12 @@ +using DMS.Core.Models; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace DMS.Infrastructure.Interfaces +{ + public interface IDeviceService + { + Task DeleteAsync(Device device, List menus); + Task AddAsync(Device device); + } +} \ No newline at end of file diff --git a/DMS.Infrastructure/Repositories/BaseRepository.cs b/DMS.Infrastructure/Repositories/BaseRepository.cs index b047ba7..1c2f3b4 100644 --- a/DMS.Infrastructure/Repositories/BaseRepository.cs +++ b/DMS.Infrastructure/Repositories/BaseRepository.cs @@ -8,81 +8,75 @@ using System.Linq.Expressions; namespace DMS.Infrastructure.Repositories; -public abstract class BaseRepository +public abstract class BaseRepository where TEntity : class, new() - where TModel : class, new() { - protected readonly IMapper _mapper; - private readonly SqlSugarDbContext dbContext; + private readonly ITransaction _transaction; - protected SqlSugarClient Db => dbContext.GetInstance(); + protected SqlSugarClient Db => _transaction.GetInstance(); - protected BaseRepository(IMapper mapper, ITransaction transaction) + protected BaseRepository(ITransaction transaction) { - _mapper = mapper; - this.dbContext = dbContext; + this._transaction = transaction; } - public virtual async Task AddAsync(TModel model) + public virtual async Task AddAsync(TEntity entity) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - var entity = _mapper.Map(model); - var result = await Db.Insertable(entity).ExecuteCommandAsync(); + var result = await Db.Insertable(entity).ExecuteReturnEntityAsync(); stopwatch.Stop(); - NlogHelper.Info($"Add {typeof(TModel).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + NlogHelper.Info($"Add {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } - public virtual async Task UpdateAsync(TModel model) + public virtual async Task UpdateAsync(TEntity entity) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - var entity = _mapper.Map(model); var result = await Db.Updateable(entity).ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Update {typeof(TModel).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + NlogHelper.Info($"Update {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } - public virtual async Task DeleteAsync(TModel model) + public virtual async Task DeleteAsync(TEntity entity) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - var entity = _mapper.Map(model); var result = await Db.Deleteable(entity).ExecuteCommandAsync(); stopwatch.Stop(); - NlogHelper.Info($"Delete {typeof(TModel).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + NlogHelper.Info($"Delete {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } - public virtual async Task> GetAllAsync() + public virtual async Task> GetAllAsync() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); var entities = await Db.Queryable().ToListAsync(); stopwatch.Stop(); - NlogHelper.Info($"GetAll {typeof(TModel).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); - return _mapper.Map>(entities); + NlogHelper.Info($"GetAll {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + return entities; } - public virtual async Task GetByIdAsync(int id) + public virtual async Task GetByIdAsync(int id) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); var entity = await Db.Queryable().In(id).FirstAsync(); stopwatch.Stop(); - NlogHelper.Info($"GetById {typeof(TModel).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); - return _mapper.Map(entity); + NlogHelper.Info($"GetById {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + return entity; } - public virtual async Task GetByConditionAsync(Expression> expression) + public virtual async Task GetByConditionAsync(Expression> expression) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); var entity = await Db.Queryable().FirstAsync(expression); stopwatch.Stop(); - NlogHelper.Info($"GetByCondition {typeof(TModel).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); - return _mapper.Map(entity); + NlogHelper.Info($"GetByCondition {typeof(TEntity).Name}耗时:{stopwatch.ElapsedMilliseconds}ms"); + return entity; } } diff --git a/DMS.Infrastructure/Repositories/DeviceRepository.cs b/DMS.Infrastructure/Repositories/DeviceRepository.cs index 26248b8..c4309cf 100644 --- a/DMS.Infrastructure/Repositories/DeviceRepository.cs +++ b/DMS.Infrastructure/Repositories/DeviceRepository.cs @@ -10,21 +10,17 @@ using DMS.Infrastructure.Interfaces; namespace DMS.Infrastructure.Repositories; -public class DeviceRepository : BaseRepository, IDeviceRepository +public class DeviceRepository : BaseRepository { - private readonly IMenuRepository _menuRepository; - private readonly IVarTableRepository _varTableRepository; - public DeviceRepository(IMapper mapper, IMenuRepository menuRepository, IVarTableRepository varTableRepository, ITransaction transaction) - : base(mapper, transaction) + public DeviceRepository(ITransaction transaction) + : base(transaction) { - _menuRepository = menuRepository; - _varTableRepository = varTableRepository; + } - - public override async Task> GetAllAsync() + public override async Task> GetAllAsync() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); @@ -36,46 +32,10 @@ public class DeviceRepository : BaseRepository, IDeviceReposit stopwatch.Stop(); NlogHelper.Info($"加载设备列表总耗时:{stopwatch.ElapsedMilliseconds}ms"); - var devices = _mapper.Map>(dlist); - return devices; + return dlist; } - public async Task DeleteAsync(Device device, List menus) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - var result = await Db.Deleteable(new DbDevice { Id = device.Id }) - .ExecuteCommandAsync(); - // 删除变量表 - //await _varTableRepository.DeleteAsync(device.VariableTables); - - stopwatch.Stop(); - NlogHelper.Info($"删除设备:{device.Name},耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result; - } - - public async Task AddAsync(Device device) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - - //查询设备的名字是否存在 - var exist = await Db.Queryable() - .Where(d => d.Name == device.Name) - .FirstAsync(); - if (exist != null) - throw new InvalidOperationException("设备名称已经存在。"); - - // 2. 将设备添加到数据库 - var addDevice = await Db.Insertable(_mapper.Map(device)) - .ExecuteReturnEntityAsync(); - - // 4. 为新设备添加菜单 - //var addDeviceMenuId = await _menuRepository.AddAsync(addDevice); - - stopwatch.Stop(); - NlogHelper.Info($"添加设备 '{device.Name}' 及相关菜单耗时:{stopwatch.ElapsedMilliseconds}ms"); - } + } \ No newline at end of file diff --git a/DMS.Infrastructure/Repositories/MenuRepository.cs b/DMS.Infrastructure/Repositories/MenuRepository.cs index 82bee23..5b67ab3 100644 --- a/DMS.Infrastructure/Repositories/MenuRepository.cs +++ b/DMS.Infrastructure/Repositories/MenuRepository.cs @@ -10,56 +10,36 @@ using DMS.Infrastructure.Interfaces; namespace DMS.Infrastructure.Repositories; -public class MenuRepository : BaseRepository +public class MenuRepository : BaseRepository { - public MenuRepository(IMapper mapper, ITransaction transaction) - : base(mapper, transaction) + public MenuRepository(SqlSugarDbContext dbContext) + : base(dbContext) { } - public async Task DeleteAsync(MenuBean menu) + public override async Task DeleteAsync(DbMenu menu) { - return await DeleteAsync(menu, Db); + return await base.DeleteAsync(menu); } - public async Task DeleteAsync(MenuBean menu, SqlSugarClient db) - { - - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - var childList = await db.Queryable() - .ToChildListAsync(it => it.ParentId, menu.Id); - var result = await db.Deleteable(childList) - .ExecuteCommandAsync(); - stopwatch.Stop(); - NlogHelper.Info($"删除菜单 '{menu.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result; - } + - public async Task> GetMenuTreesAsync() + public async Task> GetMenuTreesAsync() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - List menuTree = new(); var dbMenuTree = await Db.Queryable() .ToTreeAsync(dm => dm.Items, dm => dm.ParentId, 0); - foreach (var dbMenu in dbMenuTree) - menuTree.Add(_mapper.Map(dbMenu)); stopwatch.Stop(); NlogHelper.Info($"获取菜单树耗时:{stopwatch.ElapsedMilliseconds}ms"); - return menuTree; + return dbMenuTree; } - public async Task AddAsync(MenuBean menu) + public override async Task AddAsync(DbMenu menu) { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - var result = await AddAsync(menu, Db); - stopwatch.Stop(); - NlogHelper.Info($"添加菜单 '{menu.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result; + return await base.AddAsync(menu); } @@ -69,36 +49,10 @@ public class MenuRepository : BaseRepository /// /// /// - public async Task AddAsync(MenuBean menu, SqlSugarClient db) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - var result = await db.Insertable(_mapper.Map(menu)) - .ExecuteCommandAsync(); - stopwatch.Stop(); - NlogHelper.Info($"添加菜单 '{menu.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result; - } + - public async Task AddVarTableMenuAsync(DbDevice dbDevice, int parentMenuId, SqlSugarClient db) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - var addVarTable = new MenuBean() - { - Name = "添加变量表", - // Icon = SegoeFluentIcons.Add.Glyph, - Type = MenuType.AddVariableTableMenu, - ParentId = parentMenuId, - DataId = dbDevice.Id - }; - var addTableRes = await db.Insertable(addVarTable) - .ExecuteCommandAsync(); - stopwatch.Stop(); - // NlogHelper.Info($"添加变量表菜单 '{addVarTable.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return addTableRes; - } + /// @@ -108,44 +62,16 @@ public class MenuRepository : BaseRepository /// /// /// - public async Task AddAsync(DbDevice device, SqlSugarClient db) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - var deviceMainMenu = await db.Queryable() - .FirstAsync(m => m.Name == "设备"); - if (deviceMainMenu == null) - throw new InvalidOperationException("没有找到设备菜单!!"); - - // 添加菜单项 - MenuBean menu = new MenuBean() - { - Name = device.Name, - Type = MenuType.DeviceMenu, - DataId = device.Id, - // Icon = SegoeFluentIcons.Devices4.Glyph, - }; - menu.ParentId = deviceMainMenu.Id; - var addDeviceMenuId = await db.Insertable(_mapper.Map(menu)) - .ExecuteReturnIdentityAsync(); - stopwatch.Stop(); - NlogHelper.Info($"添加设备菜单 '{device.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return addDeviceMenuId; - } + /// /// 编辑菜单 /// /// /// - public async Task UpdateAsync(MenuBean menu) + public override async Task UpdateAsync(DbMenu menu) { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - var result = await UpdateAsync(menu, Db); - stopwatch.Stop(); - NlogHelper.Info($"编辑菜单 '{menu.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result; + return await base.UpdateAsync(menu); } /// @@ -153,18 +79,9 @@ public class MenuRepository : BaseRepository /// /// /// - public async Task UpdateAsync(MenuBean menu, SqlSugarClient db) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - var result = await db.Updateable(_mapper.Map(menu)) - .ExecuteCommandAsync(); - stopwatch.Stop(); - NlogHelper.Info($"编辑菜单 '{menu.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result; - } + - public async Task GetMenuByDataIdAsync(int dataId, MenuType menuType) + public async Task GetMenuByDataIdAsync(int dataId, MenuType menuType) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); @@ -172,12 +89,12 @@ public class MenuRepository : BaseRepository .FirstAsync(m => m.DataId == dataId && m.Type == menuType); stopwatch.Stop(); NlogHelper.Info($"根据DataId '{dataId}' 和 MenuType '{menuType}' 获取菜单耗时:{stopwatch.ElapsedMilliseconds}ms"); - return _mapper.Map(result); + return result; } - public async Task GetMainMenuByNameAsync(string name) + public async Task GetMainMenuByNameAsync(string name) { var dbMenu= await Db.Queryable().FirstAsync(m => m.Name == name && m.Type == MenuType.MainMenu); - return _mapper.Map(dbMenu); + return dbMenu; } } \ No newline at end of file diff --git a/DMS.Infrastructure/Repositories/MqttRepository.cs b/DMS.Infrastructure/Repositories/MqttRepository.cs index 310f48a..ed3107a 100644 --- a/DMS.Infrastructure/Repositories/MqttRepository.cs +++ b/DMS.Infrastructure/Repositories/MqttRepository.cs @@ -12,14 +12,12 @@ namespace DMS.Infrastructure.Repositories; /// /// Mqtt仓储类,用于操作DbMqtt实体 /// -public class MqttRepository : BaseRepository +public class MqttRepository : BaseRepository { - private readonly MenuRepository _menuRepository; - public MqttRepository(MenuRepository menuRepository, IMapper mapper, ITransaction transaction) - : base(mapper, transaction) + public MqttRepository(SqlSugarDbContext dbContext) + : base(dbContext) { - _menuRepository = menuRepository; } /// @@ -27,7 +25,7 @@ public class MqttRepository : BaseRepository /// /// 主键ID /// - public async Task GetByIdAsync(int id) + public override async Task GetByIdAsync(int id) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); @@ -36,14 +34,14 @@ public class MqttRepository : BaseRepository .SingleAsync(); stopwatch.Stop(); NlogHelper.Info($"根据ID '{id}' 获取Mqtt配置耗时:{stopwatch.ElapsedMilliseconds}ms"); - return _mapper.Map(result); + return result; } /// /// 获取所有Mqtt配置 /// /// - public async Task> GetAllAsync() + public override async Task> GetAllAsync() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); @@ -53,115 +51,8 @@ public class MqttRepository : BaseRepository .ToListAsync(); stopwatch.Stop(); NlogHelper.Info($"获取所有Mqtt配置耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result.Select(m => _mapper.Map(m)) - .ToList(); + return result; } - /// - /// 新增Mqtt配置 - /// - /// Mqtt实体 - /// - public async Task AddAsync(Mqtt mqtt) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - await Db.BeginTranAsync(); - try - { - var result = await Db.Insertable(_mapper.Map(mqtt)) - .ExecuteReturnIdentityAsync(); - var mqttMenu = await _menuRepository.GetMainMenuByNameAsync("Mqtt服务器"); - // AddAsync menu entry - var menu = new MenuBean() - { - Name = mqtt.Name, - // Icon = SegoeFluentIcons.Wifi.Glyph, - Type = MenuType.MqttMenu, - DataId = result, - ParentId = mqttMenu.Id, - }; - await _menuRepository.AddAsync(menu, Db); - await Db.CommitTranAsync(); - stopwatch.Stop(); - NlogHelper.Info($"新增Mqtt配置 '{mqtt.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result; - } - catch (Exception ex) - { - await Db.RollbackTranAsync(); - NlogHelper.Error($"添加MQTT配置 {{mqtt.Name}} 失败", ex); - throw; - } - } - /// - /// 更新Mqtt配置 - /// - /// Mqtt实体 - /// - public async Task UpdateAsync(Mqtt mqtt) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - await Db.BeginTranAsync(); - try - { - var result = await Db.Updateable(_mapper.Map(mqtt)) - .ExecuteCommandAsync(); - // Update menu entry - var menu = await _menuRepository.GetMenuByDataIdAsync(mqtt.Id, MenuType.MqttMenu); - if (menu != null) - { - menu.Name = mqtt.Name; - await _menuRepository.UpdateAsync(menu, Db); - } - - await Db.CommitTranAsync(); - stopwatch.Stop(); - NlogHelper.Info($"更新Mqtt配置 '{mqtt.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result; - } - catch (Exception ex) - { - await Db.RollbackTranAsync(); - NlogHelper.Error($"更新MQTT配置 {{mqtt.Name}} 失败", ex); - throw; - } - } - - /// - /// 根据ID删除Mqtt配置 - /// - /// Mqtt实体 - /// - public async Task DeleteAsync(Mqtt mqtt) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - await Db.BeginTranAsync(); - try - { - var result = await Db.Deleteable() - .In(mqtt.Id) - .ExecuteCommandAsync(); - // DeleteAsync menu entry - var menu = await _menuRepository.GetMenuByDataIdAsync(mqtt.Id, MenuType.MqttMenu); - if (menu != null) - { - await _menuRepository.DeleteAsync(menu, Db); - } - - await Db.CommitTranAsync(); - stopwatch.Stop(); - NlogHelper.Info($"删除Mqtt配置ID '{mqtt.Id}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result; - } - catch (Exception ex) - { - await Db.RollbackTranAsync(); - NlogHelper.Error($"删除MQTT配置 {{mqtt.Name}} 失败", ex); - throw; - } - } } \ No newline at end of file diff --git a/DMS.Infrastructure/Repositories/UserRepository.cs b/DMS.Infrastructure/Repositories/UserRepository.cs index 441c2a9..fc2bb12 100644 --- a/DMS.Infrastructure/Repositories/UserRepository.cs +++ b/DMS.Infrastructure/Repositories/UserRepository.cs @@ -9,10 +9,10 @@ namespace DMS.Infrastructure.Repositories; /// /// 用户仓储类,用于操作DbUser实体 /// -public class UserRepository : BaseRepository +public class UserRepository : BaseRepository { - public UserRepository(IMapper mapper, ITransaction transaction) - : base(mapper, transaction) + public UserRepository(SqlSugarDbContext dbContext) + : base(dbContext) { } } \ No newline at end of file diff --git a/DMS.Infrastructure/Repositories/VarDataRepository.cs b/DMS.Infrastructure/Repositories/VarDataRepository.cs index 1aaa223..b5e4e34 100644 --- a/DMS.Infrastructure/Repositories/VarDataRepository.cs +++ b/DMS.Infrastructure/Repositories/VarDataRepository.cs @@ -10,16 +10,16 @@ namespace DMS.Infrastructure.Repositories; /// /// VariableData仓储类,用于操作DbVariableData实体 /// -public class VarDataRepository : BaseRepository +public class VarDataRepository : BaseRepository { - public VarDataRepository(IMapper mapper, ITransaction transaction) - : base(mapper, transaction) + public VarDataRepository(SqlSugarDbContext dbContext) + : base(dbContext) { } - public override async Task> GetAllAsync() + public override async Task> GetAllAsync() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); @@ -29,11 +29,10 @@ public class VarDataRepository : BaseRepository .ToListAsync(); stopwatch.Stop(); //NlogHelper.Info($"获取所有VariableData耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result.Select(d => _mapper.Map(d)) - .ToList(); + return result; } - public async Task> GetByVariableTableIdAsync(int varTableId) + public async Task> GetByVariableTableIdAsync(int varTableId) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); @@ -42,21 +41,21 @@ public class VarDataRepository : BaseRepository .ToListAsync(); stopwatch.Stop(); //NlogHelper.Info($"获取变量表的所有变量{result.Count()}个耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result.Select(d => _mapper.Map(d)) - .ToList(); + return result; } - public override async Task AddAsync(Variable variable) - { - Stopwatch stopwatch = new Stopwatch(); - stopwatch.Start(); - var dbVarData = await Db.Insertable(_mapper.Map(variable)) - .ExecuteReturnEntityAsync(); - stopwatch.Stop(); - //NlogHelper.Info($"新增VariableData '{variable.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return dbVarData.Id; - } + //public override async Task AddAsync(DbVariable entity) + //{ + // Stopwatch stopwatch = new Stopwatch(); + // stopwatch.Start(); + // var dbVarData = await Db.Insertable(entity) + // .ExecuteReturnEntityAsync(); + // stopwatch.Stop(); + // //NlogHelper.Info($"新增VariableData '{entity.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + // return dbVarData.Id; + //} + /* public async Task AddAsync(IEnumerable variableDatas) { Stopwatch stopwatch = new Stopwatch(); @@ -75,19 +74,21 @@ public class VarDataRepository : BaseRepository //NlogHelper.Info($"新增VariableData '{variableDatas.Count()}'个, 耗时:{stopwatch.ElapsedMilliseconds}ms"); return res; } +*/ - public override async Task UpdateAsync(Variable variable) + public override async Task UpdateAsync(DbVariable entity) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - var result = await Db.Updateable(_mapper.Map(variable)) + var result = await Db.Updateable(entity) .ExecuteCommandAsync(); stopwatch.Stop(); - //NlogHelper.Info($"更新VariableData '{variable.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + //NlogHelper.Info($"更新VariableData '{entity.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } + /* public async Task UpdateAsync(List variableDatas) { Stopwatch stopwatch = new Stopwatch(); @@ -101,19 +102,21 @@ public class VarDataRepository : BaseRepository //NlogHelper.Info($"更新VariableData {variableDatas.Count()}个 耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } +*/ - public override async Task DeleteAsync(Variable variable) + public override async Task DeleteAsync(DbVariable entity) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); var result = await Db.Deleteable() - .Where(d => d.Id == variable.Id) + .Where(d => d.Id == entity.Id) .ExecuteCommandAsync(); stopwatch.Stop(); - //NlogHelper.Info($"删除VariableData: '{variable.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + //NlogHelper.Info($"删除VariableData: '{entity.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } + /* public async Task DeleteAsync(IEnumerable variableDatas) { Stopwatch stopwatch = new Stopwatch(); @@ -128,12 +131,14 @@ public class VarDataRepository : BaseRepository //NlogHelper.Info($"删除VariableData: '{variableDatas.Count()}'个 耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } +*/ // public VarDataRepository(IMapper mapper) // { // _mapper = mapper; // } + /* /// /// 为变量添加MQTT服务器关联,并指定别名。 /// @@ -156,7 +161,7 @@ public class VarDataRepository : BaseRepository .ToListAsync(); var existingAliasesDict = existingAliases - .ToDictionary(a => (a.VariableId, a.MqttId), a => a); + .ToDictionary(a => (a.VariableId, a.Mqtt.Id), a => a); var toInsert = new List(); var toUpdate = new List(); @@ -214,4 +219,5 @@ public class VarDataRepository : BaseRepository throw; } } +*/ } \ No newline at end of file diff --git a/DMS.Infrastructure/Repositories/VarTableRepository.cs b/DMS.Infrastructure/Repositories/VarTableRepository.cs index 10ad2fa..d16d647 100644 --- a/DMS.Infrastructure/Repositories/VarTableRepository.cs +++ b/DMS.Infrastructure/Repositories/VarTableRepository.cs @@ -7,10 +7,10 @@ using DMS.Infrastructure.Data; namespace DMS.Infrastructure.Repositories; -public class VarTableRepository : BaseRepository +public class VarTableRepository : BaseRepository { - public VarTableRepository(IMapper mapper, ITransaction transaction) - : base(mapper, transaction) + public VarTableRepository(SqlSugarDbContext dbContext) + : base(dbContext) { } @@ -19,16 +19,16 @@ public class VarTableRepository : BaseRepository /// /// /// 变量表的ID - public async Task AddAsync(VariableTable varTable) + public override async Task AddAsync(DbVariableTable entity) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - var addVarTabel = await Db.Insertable(_mapper.Map(varTable)) + var addVarTabel = await Db.Insertable(entity) .ExecuteReturnEntityAsync(); stopwatch.Stop(); - //NlogHelper.Info($"添加变量表 '{varTable.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); - return _mapper.Map(addVarTabel); + //NlogHelper.Info($"添加变量表 '{entity.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return addVarTabel; } /// @@ -36,14 +36,14 @@ public class VarTableRepository : BaseRepository /// /// /// - public async Task UpdateAsync(VariableTable variableTable) + public override async Task UpdateAsync(DbVariableTable entity) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - var result = await Db.Updateable(_mapper.Map(variableTable)) + var result = await Db.Updateable(entity) .ExecuteCommandAsync(); stopwatch.Stop(); - //NlogHelper.Info($"编辑变量表 '{variableTable.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + //NlogHelper.Info($"编辑变量表 '{entity.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } @@ -52,17 +52,17 @@ public class VarTableRepository : BaseRepository /// /// /// - public async Task DeleteAsync(VariableTable varTable) + public override async Task DeleteAsync(DbVariableTable entity) { - if (varTable == null ) + if (entity == null ) return 0; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 转换对象 - var res= await Db.Deleteable(_mapper.Map(varTable)) + var res= await Db.Deleteable(entity) .ExecuteCommandAsync(); stopwatch.Stop(); - //NlogHelper.Info($"删除变量表 '{varTable.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + //NlogHelper.Info($"删除变量表 '{entity.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); return res; } @@ -71,14 +71,12 @@ public class VarTableRepository : BaseRepository /// /// /// - public async Task DeleteAsync(IEnumerable deviceVariableTables) + public async Task DeleteAsync(IEnumerable deviceVariableTables) { if (deviceVariableTables == null || deviceVariableTables.Count() == 0) return; // 转换对象 - var dbList = deviceVariableTables.Select(v => _mapper.Map(v)) - .ToList(); - await Db.Deleteable(dbList) + await Db.Deleteable(deviceVariableTables) .ExecuteCommandAsync(); } diff --git a/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs b/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs index 3ca4ad6..aa5b8d4 100644 --- a/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs +++ b/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs @@ -9,10 +9,10 @@ namespace DMS.Infrastructure.Repositories; /// /// 变量与MQTT服务器别名关联的数据仓库。 /// -public class VariableMqttAliasRepository : BaseRepository +public class VariableMqttAliasRepository : BaseRepository { - public VariableMqttAliasRepository(IMapper mapper, ITransaction transaction) - : base(mapper, transaction) + public VariableMqttAliasRepository(SqlSugarDbContext dbContext) + : base(dbContext) { } } diff --git a/DMS.Infrastructure/Services/DeviceService.cs b/DMS.Infrastructure/Services/DeviceService.cs new file mode 100644 index 0000000..09281e9 --- /dev/null +++ b/DMS.Infrastructure/Services/DeviceService.cs @@ -0,0 +1,71 @@ +using AutoMapper; +using DMS.Core.Helper; +using DMS.Core.Models; +using DMS.Infrastructure.Data; +using DMS.Infrastructure.Entities; +using DMS.Infrastructure.Repositories; +using DMS.Infrastructure.Interfaces; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; + +namespace DMS.Infrastructure.Services +{ + public class DeviceService : IDeviceService + { + private readonly DeviceRepository _deviceRepository; + private readonly IMenuRepository _menuRepository; + private readonly IVarTableRepository _varTableRepository; + private readonly IMapper _mapper; + private readonly SqlSugarClient Db; // Assuming DbContext is accessible or passed + + public DeviceService(DeviceRepository deviceRepository, IMenuRepository menuRepository, IVarTableRepository varTableRepository, IMapper mapper, SqlSugarDbContext dbContext) + { + _deviceRepository = deviceRepository; + _menuRepository = menuRepository; + _varTableRepository = varTableRepository; + _mapper = mapper; + Db = dbContext.GetInstance(); + } + + public async Task DeleteAsync(Device device, List menus) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var result = await Db.Deleteable(new DbDevice { Id = device.Id }) + .ExecuteCommandAsync(); + // 删除变量表 + //await _varTableRepository.DeleteAsync(device.VariableTables); + + stopwatch.Stop(); + NlogHelper.Info($"删除设备:{device.Name},耗时:{stopwatch.ElapsedMilliseconds}ms"); + return result; + } + + public async Task AddAsync(Device device) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + + //查询设备的名字是否存在 + var exist = await Db.Queryable() + .Where(d => d.Name == device.Name) + .FirstAsync(); + if (exist != null) + throw new InvalidOperationException("设备名称已经存在。"); + + // 2. 将设备添加到数据库 + var addDevice = await Db.Insertable(_mapper.Map(device)) + .ExecuteReturnEntityAsync(); + + // 4. 为新设备添加菜单 + //var addDeviceMenuId = await _menuRepository.AddAsync(addDevice); + + stopwatch.Stop(); + NlogHelper.Info($"添加设备 '{device.Name}' 及相关菜单耗时:{stopwatch.ElapsedMilliseconds}ms"); + } + } +} diff --git a/DMS.Infrastructure/Services/MenuService.cs b/DMS.Infrastructure/Services/MenuService.cs new file mode 100644 index 0000000..2e8dc1a --- /dev/null +++ b/DMS.Infrastructure/Services/MenuService.cs @@ -0,0 +1,102 @@ +using AutoMapper; +using DMS.Core.Enums; +using DMS.Core.Helper; +using DMS.Core.Models; +using DMS.Infrastructure.Data; +using DMS.Infrastructure.Entities; +using SqlSugar; +using System.Diagnostics; +using System.Collections.Generic; +using System; +using System.Threading.Tasks; + +namespace DMS.Infrastructure.Services +{ + public class MenuService + { + private readonly IMapper _mapper; + private readonly SqlSugarDbContext _dbContext; + private SqlSugarClient Db => _dbContext.GetInstance(); + + public MenuService(IMapper mapper, SqlSugarDbContext dbContext) + { + _mapper = mapper; + _dbContext = dbContext; + } + + public async Task DeleteAsync(MenuBean menu, SqlSugarClient db) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var childList = await db.Queryable() + .ToChildListAsync(it => it.ParentId, menu.Id); + var result = await db.Deleteable(childList) + .ExecuteCommandAsync(); + stopwatch.Stop(); + NlogHelper.Info($"删除菜单 '{menu.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return result; + } + + public async Task AddAsync(MenuBean menu, SqlSugarClient db) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var result = await db.Insertable(_mapper.Map(menu)) + .ExecuteCommandAsync(); + stopwatch.Stop(); + NlogHelper.Info($"添加菜单 '{menu.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return result; + } + + public async Task AddVarTableMenuAsync(DbDevice dbDevice, int parentMenuId, SqlSugarClient db) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var addVarTable = new MenuBean() + { + Name = "添加变量表", + Type = MenuType.AddVariableTableMenu, + ParentId = parentMenuId, + DataId = dbDevice.Id + }; + var addTableRes = await db.Insertable(addVarTable) + .ExecuteCommandAsync(); + stopwatch.Stop(); + return addTableRes; + } + + public async Task AddAsync(DbDevice device, SqlSugarClient db) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var deviceMainMenu = await db.Queryable() + .FirstAsync(m => m.Name == "设备"); + if (deviceMainMenu == null) + throw new InvalidOperationException("没有找到设备菜单!!"); + + MenuBean menu = new MenuBean() + { + Name = device.Name, + Type = MenuType.DeviceMenu, + DataId = device.Id, + }; + menu.ParentId = deviceMainMenu.Id; + var addDeviceMenuId = await db.Insertable(_mapper.Map(menu)) + .ExecuteReturnIdentityAsync(); + stopwatch.Stop(); + NlogHelper.Info($"添加设备菜单 '{device.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return addDeviceMenuId; + } + + public async Task UpdateAsync(MenuBean menu, SqlSugarClient db) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var result = await db.Updateable(_mapper.Map(menu)) + .ExecuteCommandAsync(); + stopwatch.Stop(); + NlogHelper.Info($"编辑菜单 '{menu.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return result; + } + } +} diff --git a/DMS.Infrastructure/Services/MqttService.cs b/DMS.Infrastructure/Services/MqttService.cs new file mode 100644 index 0000000..08b810b --- /dev/null +++ b/DMS.Infrastructure/Services/MqttService.cs @@ -0,0 +1,124 @@ +using AutoMapper; +using DMS.Core.Enums; +using DMS.Core.Helper; +using DMS.Core.Models; +using DMS.Infrastructure.Data; +using DMS.Infrastructure.Entities; +using DMS.Infrastructure.Repositories; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; + +namespace DMS.Infrastructure.Services +{ + public class MqttService + { + private readonly MqttRepository _mqttRepository; + private readonly MenuRepository _menuRepository; + private readonly IMapper _mapper; + private readonly SqlSugarDbContext _dbContext; + private SqlSugarClient Db => _dbContext.GetInstance(); + + public MqttService(MqttRepository mqttRepository, MenuRepository menuRepository, IMapper mapper, SqlSugarDbContext dbContext) + { + _mqttRepository = mqttRepository; + _menuRepository = menuRepository; + _mapper = mapper; + _dbContext = dbContext; + } + + public async Task AddAsync(Mqtt mqtt) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + await Db.BeginTranAsync(); + try + { + var result = await Db.Insertable(_mapper.Map(mqtt)) + .ExecuteReturnIdentityAsync(); + var mqttMenu = await _menuRepository.GetMainMenuByNameAsync("Mqtt服务器"); + // AddAsync menu entry + var menu = new MenuBean() + { + Name = mqtt.Name, + Type = MenuType.MqttMenu, + DataId = result, + ParentId = mqttMenu.Id, + }; + await _menuRepository.AddAsync(_mapper.Map(menu)); + await Db.CommitTranAsync(); + stopwatch.Stop(); + NlogHelper.Info($"新增Mqtt配置 '{mqtt.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return result; + } + catch (Exception ex) + { + await Db.RollbackTranAsync(); + NlogHelper.Error($"添加MQTT配置 {mqtt.Name} 失败", ex); + throw; + } + } + + public async Task UpdateAsync(Mqtt mqtt) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + await Db.BeginTranAsync(); + try + { + var result = await Db.Updateable(_mapper.Map(mqtt)) + .ExecuteCommandAsync(); + // Update menu entry + var menu = await _menuRepository.GetMenuByDataIdAsync(mqtt.Id, MenuType.MqttMenu); + if (menu != null) + { + menu.Name = mqtt.Name; + await _menuRepository.UpdateAsync(_mapper.Map(menu)); + } + + await Db.CommitTranAsync(); + stopwatch.Stop(); + NlogHelper.Info($"更新Mqtt配置 '{mqtt.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return result; + } + catch (Exception ex) + { + await Db.RollbackTranAsync(); + NlogHelper.Error($"更新MQTT配置 {mqtt.Name} 失败", ex); + throw; + } + } + + public async Task DeleteAsync(Mqtt mqtt) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + await Db.BeginTranAsync(); + try + { + var result = await Db.Deleteable() + .In(mqtt.Id) + .ExecuteCommandAsync(); + // DeleteAsync menu entry + var menu = await _menuRepository.GetMenuByDataIdAsync(mqtt.Id, MenuType.MqttMenu); + if (menu != null) + { + await _menuRepository.DeleteAsync(_mapper.Map(menu)); + } + + await Db.CommitTranAsync(); + stopwatch.Stop(); + NlogHelper.Info($"删除Mqtt配置ID '{mqtt.Id}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return result; + } + catch (Exception ex) + { + await Db.RollbackTranAsync(); + NlogHelper.Error($"删除MQTT配置 {mqtt.Name} 失败", ex); + throw; + } + } + } +} diff --git a/DMS.Infrastructure/Services/VarDataService.cs b/DMS.Infrastructure/Services/VarDataService.cs new file mode 100644 index 0000000..c25c321 --- /dev/null +++ b/DMS.Infrastructure/Services/VarDataService.cs @@ -0,0 +1,150 @@ +using AutoMapper; +using DMS.Core.Helper; +using DMS.Core.Models; +using DMS.Infrastructure.Data; +using DMS.Infrastructure.Entities; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; + +namespace DMS.Infrastructure.Services +{ + public class VarDataService + { + private readonly IMapper _mapper; + private readonly SqlSugarDbContext _dbContext; + private SqlSugarClient Db => _dbContext.GetInstance(); + + public VarDataService(IMapper mapper, SqlSugarDbContext dbContext) + { + _mapper = mapper; + _dbContext = dbContext; + } + + public async Task AddAsync(IEnumerable variableDatas) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + Stopwatch stopwatch2 = new Stopwatch(); + stopwatch2.Start(); + var dbList = variableDatas.Select(vb => _mapper.Map(vb)) + .ToList(); + stopwatch2.Stop(); + //NlogHelper.Info($"复制 Variable'{variableDatas.Count()}'个, 耗时:{stopwatch2.ElapsedMilliseconds}ms"); + + var res = await Db.Insertable(dbList) + .ExecuteCommandAsync(); + + stopwatch.Stop(); + //NlogHelper.Info($"新增VariableData '{variableDatas.Count()}'个, 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return res; + } + + public async Task UpdateAsync(List variableDatas) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + + var dbVarDatas = variableDatas.Select(vd => _mapper.Map(vd)); + var result = await Db.Updateable(dbVarDatas.ToList()) + .ExecuteCommandAsync(); + + stopwatch.Stop(); + //NlogHelper.Info($"更新VariableData {variableDatas.Count()}个 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return result; + } + + public async Task DeleteAsync(IEnumerable variableDatas) + { + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + + 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"); + return result; + } + + public async Task AddMqttToVariablesAsync(IEnumerable variableMqttList) + { + await Db.BeginTranAsync(); + + try + { + int affectedCount = 0; + var variableIds = variableMqttList.Select(vm => vm.Variable.Id).Distinct().ToList(); + var mqttIds = variableMqttList.Select(vm => vm.Mqtt.Id).Distinct().ToList(); + + // 1. 一次性查询所有相关的现有别名 + var existingAliases = await Db.Queryable() + .Where(it => variableIds.Contains(it.VariableId) && mqttIds.Contains(it.MqttId)) + .ToListAsync(); + + var existingAliasesDict = existingAliases + .ToDictionary(a => (a.VariableId, a.Mqtt.Id), a => a); + + var toInsert = new List(); + var toUpdate = new List(); + + foreach (var variableMqtt in variableMqttList) + { + var key = (variableMqtt.Variable.Id, variableMqtt.Mqtt.Id); + if (existingAliasesDict.TryGetValue(key, out var existingAlias)) + { + // 如果存在但别名不同,则准备更新 + // if (existingAlias.MqttAlias != variableMqtt.MqttAlias) + // { + // existingAlias.MqttAlias = variableMqtt.MqttAlias; + // existingAlias.UpdateTime = DateTime.Now; + // toUpdate.Add(existingAlias); + // } + } + else + { + // 如果不存在,则准备插入 + toInsert.Add(new DbVariableMqtt + { + VariableId = variableMqtt.Variable.Id, + MqttId = variableMqtt.Mqtt.Id, + // MqttAlias = variableMqtt.MqttAlias, + CreateTime = DateTime.Now, + UpdateTime = DateTime.Now + }); + } + } + + // 2. 批量更新 + if (toUpdate.Any()) + { + var updateResult = await Db.Updateable(toUpdate).ExecuteCommandAsync(); + affectedCount += updateResult; + } + + // 3. 批量插入 + if (toInsert.Any()) + { + var insertResult = await Db.Insertable(toInsert).ExecuteCommandAsync(); + affectedCount += insertResult; + } + + await Db.CommitTranAsync(); + //NlogHelper.Info($"成功为 {variableMqttList.Count()} 个变量请求添加/更新了MQTT服务器关联,实际影响 {affectedCount} 个。"); + return affectedCount; + } + catch (Exception ex) + { + await Db.RollbackTranAsync(); + //NlogHelper.Error($"为变量添加MQTT服务器关联时发生错误: {ex.Message}", ex); + // 根据需要,可以向上层抛出异常 + throw; + } + } + } +} diff --git a/DMS.WPF/App.xaml.cs b/DMS.WPF/App.xaml.cs index 1b0269a..f2bc58e 100644 --- a/DMS.WPF/App.xaml.cs +++ b/DMS.WPF/App.xaml.cs @@ -113,10 +113,10 @@ public partial class App : System.Windows.Application services.AddScoped(); // Register ITransaction (abstract interface for transaction management) - services.AddScoped(); + //services.AddScoped(); - // Register IDatabaseService (abstract interface for database initialization) - services.AddSingleton(); + //// Register IDatabaseService (abstract interface for database initialization) + //services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -125,6 +125,7 @@ public partial class App : System.Windows.Application services.AddHostedService(); services.AddHostedService(); services.AddSingleton(); + services.AddSingleton(); services.AddHostedService(provider => provider.GetRequiredService()); services.AddSingleton(); @@ -156,7 +157,7 @@ public partial class App : System.Windows.Application services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddScoped(); + //services.AddScoped(); services.AddSingleton(); services.AddScoped(); //注册View视图 diff --git a/DMS.WPF/Services/ChannelBusService.cs b/DMS.WPF/Services/ChannelBusService.cs new file mode 100644 index 0000000..91dbe50 --- /dev/null +++ b/DMS.WPF/Services/ChannelBusService.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Concurrent; +using System.Threading; +using System.Threading.Channels; +using System.Threading.Tasks; + +namespace DMS.WPF.Services +{ + /// + /// 标记接口,用于标识可以通过ChannelBusService发送的消息。 + /// + public interface IChannelMessage { } + + /// + /// 提供基于System.Threading.Channels的消息发布/订阅机制,实现组件解耦。 + /// + public class ChannelBusService + { + // 使用ConcurrentDictionary存储不同消息类型的Channel + private readonly ConcurrentDictionary _channels = new ConcurrentDictionary(); + + /// + /// 异步发布一条消息到对应的Channel。 + /// + /// 消息的类型,必须实现IChannelMessage接口。 + /// 要发布的消息实例。 + /// 取消令牌。 + /// 表示异步操作的Task。 + public async ValueTask PublishAsync(TMessage message, CancellationToken cancellationToken = default) + where TMessage : IChannelMessage + { + var channel = GetOrCreateChannel(); + await channel.Writer.WriteAsync(message, cancellationToken); + } + + /// + /// 获取指定消息类型的ChannelReader,用于订阅消息。 + /// + /// 要订阅的消息类型,必须实现IChannelMessage接口。 + /// 指定消息类型的ChannelReader。 + public ChannelReader Subscribe() + where TMessage : IChannelMessage + { + var channel = GetOrCreateChannel(); + return channel.Reader; + } + + /// + /// 获取或创建指定消息类型的Channel。 + /// + /// 消息类型。 + /// 指定消息类型的Channel。 + private Channel GetOrCreateChannel() + where TMessage : IChannelMessage + { + // 使用GetOrAdd方法确保线程安全地获取或创建Channel + return (Channel)_channels.GetOrAdd(typeof(TMessage), _ => Channel.CreateUnbounded()); + } + } +} diff --git a/DMS.sln b/DMS.sln index 7cfaeb6..67ed7ea 100644 --- a/DMS.sln +++ b/DMS.sln @@ -20,6 +20,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DMS.WPF", "DMS.WPF\DMS.WPF. {46E180A5-38CB-4229-915F-C9BC44534E77} = {46E180A5-38CB-4229-915F-C9BC44534E77} EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DMS.Infrastructure.UnitTests", "DMS.Infrastructure.UnitTests\DMS.Infrastructure.UnitTests.csproj", "{98D739FC-6184-4FC6-961F-F12ED57B0CC4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -42,6 +44,10 @@ Global {6059F299-9EE8-4A3F-8CD2-D00E2BDB5D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU {6059F299-9EE8-4A3F-8CD2-D00E2BDB5D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU {6059F299-9EE8-4A3F-8CD2-D00E2BDB5D5F}.Release|Any CPU.Build.0 = Release|Any CPU + {98D739FC-6184-4FC6-961F-F12ED57B0CC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {98D739FC-6184-4FC6-961F-F12ED57B0CC4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {98D739FC-6184-4FC6-961F-F12ED57B0CC4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {98D739FC-6184-4FC6-961F-F12ED57B0CC4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE