From a1de03a94e84f1c72959664919f35d849bf98a8f Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Mon, 30 Jun 2025 20:11:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD=E6=9C=AA=20=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data/Entities/DbMenu.cs | 2 + Data/Entities/DbVariableTable.cs | 2 +- Data/Repositories/DeviceRepository.cs | 2 +- Data/Repositories/MenuRepository.cs | 55 ++++--- Data/Repositories/VariableTableRepository.cs | 2 +- Extensions/ObjectExtensions.cs | 144 ++++++++++--------- Models/MenuBean.cs | 2 + 7 files changed, 119 insertions(+), 90 deletions(-) diff --git a/Data/Entities/DbMenu.cs b/Data/Entities/DbMenu.cs index 8c0f3c4..2ac2386 100644 --- a/Data/Entities/DbMenu.cs +++ b/Data/Entities/DbMenu.cs @@ -21,4 +21,6 @@ public class DbMenu [SugarColumn(IsIgnore = true)] public List Items { get; set; } + + public DbMenu? Parent { get; set; } } \ No newline at end of file diff --git a/Data/Entities/DbVariableTable.cs b/Data/Entities/DbVariableTable.cs index d294abf..dfcdaea 100644 --- a/Data/Entities/DbVariableTable.cs +++ b/Data/Entities/DbVariableTable.cs @@ -24,5 +24,5 @@ public class DbVariableTable [SugarColumn(IsNullable = true)] public int? DeviceId { get; set; } [Navigate(NavigateType.ManyToOne, nameof(DeviceId))] - public Device? Device { get; set; } + public DbDevice? Device { get; set; } } \ No newline at end of file diff --git a/Data/Repositories/DeviceRepository.cs b/Data/Repositories/DeviceRepository.cs index 60d666a..f6ff367 100644 --- a/Data/Repositories/DeviceRepository.cs +++ b/Data/Repositories/DeviceRepository.cs @@ -34,7 +34,7 @@ public class DeviceRepository public async Task> GetAll() { - var dlist = await _db.Queryable().Includes(d => d.VariableTables).ToListAsync(); + var dlist = await _db.Queryable().Includes(d => d.VariableTables,dv=>dv.Device).ToListAsync(); var devices = new List(); foreach (var dbDevice in dlist) { diff --git a/Data/Repositories/MenuRepository.cs b/Data/Repositories/MenuRepository.cs index 6e4da95..091e206 100644 --- a/Data/Repositories/MenuRepository.cs +++ b/Data/Repositories/MenuRepository.cs @@ -24,14 +24,34 @@ public class MenuRepository { // //无主键用法新:5.1.4.110 // db.Queryable().ToTree(it=>it.Child,it=>it.ParentId,0,it=>it.Id)//+4重载 - List menus = new(); - var dbMenuList = await _db.Queryable().ToTreeAsync(dm => dm.Items, dm => dm.ParentId, 0); - foreach (var item in dbMenuList) + List dbMenuList = await _db.Queryable().ToListAsync(); + + List menuTree = new(); + var dbMenuTree = await _db.Queryable().ToTreeAsync(dm => dm.Items, dm => dm.ParentId, 0); + foreach (var dbMenu in dbMenuTree) { - menus.Add(item.CopyTo()); + AddParent(dbMenu); + menuTree.Add(dbMenu.CopyTo()); } - return menus; + return menuTree; + } + + private void AddParent(DbMenu dbMenu) + { + if (dbMenu.Items == null || dbMenu.Items.Count == 0) + return; + foreach (var item in dbMenu.Items) + { + item.Parent = dbMenu; + if (item.Items!=null && item.Items.Count>0) + { + AddParent(item); + } + + } + + } public async Task AddMenu(MenuBean menu) @@ -46,7 +66,7 @@ public class MenuRepository var deviceMainMenu = await _db.Queryable().FirstAsync(m => m.Name == "设备"); if (deviceMainMenu == null) throw new InvalidOperationException("没有找到设备菜单!!"); - + // 添加菜单项 MenuBean menu = new MenuBean() { @@ -56,16 +76,17 @@ public class MenuRepository Icon = SegoeFluentIcons.Devices4.Glyph, }; - menu.ParentId=deviceMainMenu.Id; + menu.ParentId = deviceMainMenu.Id; var addDeviceMenuId = await _db.Insertable(menu.CopyTo()) .ExecuteReturnIdentityAsync(); if (addDeviceMenuId == 0) throw new InvalidOperationException($"{menu.Name},设备菜单添加失败!!"); - - var defVarTable= await _db.Queryable().FirstAsync(v=>v.DeviceId==device.Id && v.Name=="默认变量表"); - if (defVarTable == null) - throw new InvalidOperationException($"没有找到{device.Name}的默认变量表。"); - var defVarTableMenu=new MenuBean() + + var defVarTable = await _db.Queryable() + .FirstAsync(v => v.DeviceId == device.Id && v.Name == "默认变量表"); + if (defVarTable == null) + throw new InvalidOperationException($"没有找到{device.Name}的默认变量表。"); + var defVarTableMenu = new MenuBean() { Name = "默认变量表", Icon = SegoeFluentIcons.Tablet.Glyph, @@ -73,7 +94,7 @@ public class MenuRepository ParentId = addDeviceMenuId, DataId = defVarTable.Id }; - var addVarTable=new MenuBean() + var addVarTable = new MenuBean() { Name = "添加变量表", Icon = SegoeFluentIcons.Add.Glyph, @@ -82,14 +103,14 @@ public class MenuRepository }; var defTableRes = await _db.Insertable(defVarTableMenu).ExecuteCommandAsync(); var addTableRes = await _db.Insertable(addVarTable).ExecuteCommandAsync(); - if ((addTableRes+defTableRes) != 2) + if ((addTableRes + defTableRes) != 2) { // 如果出错删除原来添加的设备菜单 - await _db.Deleteable().Where(m=>m.Id==addDeviceMenuId).ExecuteCommandAsync(); + await _db.Deleteable().Where(m => m.Id == addDeviceMenuId).ExecuteCommandAsync(); throw new InvalidOperationException("添加默认变量表时发生了错误!!"); } - + return true; } -} +} \ No newline at end of file diff --git a/Data/Repositories/VariableTableRepository.cs b/Data/Repositories/VariableTableRepository.cs index 6721c48..49ed04e 100644 --- a/Data/Repositories/VariableTableRepository.cs +++ b/Data/Repositories/VariableTableRepository.cs @@ -32,7 +32,7 @@ public class VariableTableRepository public async Task> GetAll() { - var dbVariableTables = await _db.Queryable().ToListAsync(); + var dbVariableTables = await _db.Queryable().Includes(dv=>dv.Device).ToListAsync(); var variableTables = new List(); foreach (var dbVariableTable in dbVariableTables) diff --git a/Extensions/ObjectExtensions.cs b/Extensions/ObjectExtensions.cs index b22def8..99a86e8 100644 --- a/Extensions/ObjectExtensions.cs +++ b/Extensions/ObjectExtensions.cs @@ -5,7 +5,6 @@ namespace PMSWPF.Extensions; public static class ObjectExtensions { - /// /// 复制一个新的对象并返回 /// @@ -65,6 +64,11 @@ public static class ObjectExtensions if (targetProperty != null && targetProperty.CanWrite) { object sourceValue = sourceProperty.GetValue(tsource); + // 判断源属性和目标属性是否是泛型列表 + bool isSourceList = sourceProperty.PropertyType.IsGenericType && + sourceProperty.PropertyType.GetGenericTypeDefinition() == typeof(List<>); + bool isTargetList = targetProperty.PropertyType.IsGenericType && + targetProperty.PropertyType.GetGenericTypeDefinition() == typeof(List<>); // 场景 1: 属性类型完全相同 if (targetProperty.PropertyType == sourceProperty.PropertyType) @@ -72,79 +76,82 @@ public static class ObjectExtensions targetProperty.SetValue(ttarget, sourceValue); } // 场景 2: 属性类型不同,但可能是泛型 List 类型 + else if(isTargetList && isSourceList) + { + CopyGenericList(ttarget, sourceProperty, targetProperty, sourceValue); + } else { - bool isSourceList = sourceProperty.PropertyType.IsGenericType && - sourceProperty.PropertyType.GetGenericTypeDefinition() == typeof(List<>); - bool isTargetList = targetProperty.PropertyType.IsGenericType && - targetProperty.PropertyType.GetGenericTypeDefinition() == typeof(List<>); - - if (isSourceList && isTargetList) - { - // 获取源列表的元素类型 - Type sourceListItemType = sourceProperty.PropertyType.GetGenericArguments()[0]; - // 获取目标列表的元素类型 - Type targetListItemType = targetProperty.PropertyType.GetGenericArguments()[0]; - - // 检查列表元素类型名称是否匹配(用于潜在的深拷贝) - if (sourceProperty.Name == targetProperty.Name) - { - // 如果源列表为空,则将目标属性设置为 null - if (sourceValue == null) - { - targetProperty.SetValue(ttarget, null); - continue; - } - - // 将源值强制转换为 IEnumerable 以便遍历 - var sourceList = (IEnumerable)sourceValue; - - // 创建一个目标泛型列表的新实例 - // 假设 CreateGenericList 助手方法可用,或按注释创建 - // var targetList = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(targetListItemType)); - IList targetList = CreateGenericList(targetListItemType); - - foreach (var item in sourceList) - { - // 确保列表项不为空,然后尝试深拷贝 - if (item == null) - { - // 如果源列表项为 null,则直接添加到目标列表 - targetList.Add(null); - continue; - } - - // 创建目标列表元素类型的一个实例 - var targetDataItem = Activator.CreateInstance(targetListItemType); - - // 递归调用 CopyTo,对嵌套对象进行深拷贝 - CopyTo(item, targetDataItem); - - // 将复制后的项添加到目标列表 - targetList.Add(targetDataItem); - } - - // 将填充好的目标列表设置给目标对象的属性 - targetProperty.SetValue(ttarget, targetList); - } - else - { - // 列表类型匹配,但元素类型名称不匹配。此处跳过,或可实现更复杂的转换。 - Console.WriteLine( - $"由于列表元素类型不匹配,跳过属性 '{sourceProperty.Name}':源 '{sourceListItemType.Name}',目标 '{targetListItemType.Name}'"); - } - } - else - { - // 类型不同,且都不是泛型 List。此处跳过,或可实现类型转换。 - Console.WriteLine( - $"由于类型不匹配,跳过属性 '{sourceProperty.Name}':源 '{sourceProperty.PropertyType.Name}',目标 '{targetProperty.PropertyType.Name}'"); - } + } } } } + /// + /// 复制泛型列表, + /// + /// + /// + /// + /// + private static void CopyGenericList(object ttarget, PropertyInfo sourceProperty, PropertyInfo targetProperty, + object? sourceValue) + { + // 获取源列表的元素类型 + Type sourceListItemType = sourceProperty.PropertyType.GetGenericArguments()[0]; + // 获取目标列表的元素类型 + Type targetListItemType = targetProperty.PropertyType.GetGenericArguments()[0]; + + // 检查列表元素类型名称是否匹配(用于潜在的深拷贝) + if (sourceProperty.Name == targetProperty.Name) + { + // 如果源列表为空,则将目标属性设置为 null + if (sourceValue == null) + { + targetProperty.SetValue(ttarget, null); + return; + } + + // 将源值强制转换为 IEnumerable 以便遍历 + var sourceList = (IEnumerable)sourceValue; + + // 创建一个目标泛型列表的新实例 + // 假设 CreateGenericList 助手方法可用,或按注释创建 + // var targetList = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(targetListItemType)); + IList targetList = CreateGenericList(targetListItemType); + + foreach (var item in sourceList) + { + // 确保列表项不为空,然后尝试深拷贝 + if (item == null) + { + // 如果源列表项为 null,则直接添加到目标列表 + targetList.Add(null); + continue; + } + + // 创建目标列表元素类型的一个实例 + var targetDataItem = Activator.CreateInstance(targetListItemType); + + // 递归调用 CopyTo,对嵌套对象进行深拷贝 + CopyTo(item, targetDataItem); + + // 将复制后的项添加到目标列表 + targetList.Add(targetDataItem); + } + + // 将填充好的目标列表设置给目标对象的属性 + targetProperty.SetValue(ttarget, targetList); + } + else + { + // 列表类型匹配,但元素类型名称不匹配。此处跳过,或可实现更复杂的转换。 + Console.WriteLine( + $"由于列表元素类型不匹配,跳过属性 '{sourceProperty.Name}':源 '{sourceListItemType.Name}',目标 '{targetListItemType.Name}'"); + } + } + /// /// 辅助方法,用于动态创建泛型 List。 /// @@ -155,7 +162,4 @@ public static class ObjectExtensions Type listType = typeof(List<>).MakeGenericType(itemType); return (IList)Activator.CreateInstance(listType); } - - - } \ No newline at end of file diff --git a/Models/MenuBean.cs b/Models/MenuBean.cs index 0edce88..ca14ae6 100644 --- a/Models/MenuBean.cs +++ b/Models/MenuBean.cs @@ -16,4 +16,6 @@ public class MenuBean public ViewModelBase ViewModel { get; set; } public Object? Data { get; set; } public List Items { get; set; } + + public MenuBean Parent { get; set; } } \ No newline at end of file