BUG:storageable2.BulkUpdateAsync 这句代码在达梦下会出错,回退回之前可用的版本
This commit is contained in:
parent
98d4b0de5b
commit
c116a5eb9c
@ -1,4 +1,4 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
@ -14,8 +14,8 @@ namespace Admin.NET.Core;
|
||||
public class EnumToDictJob : IJob
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
private const string DefaultTagType = null;
|
||||
private const int OrderOffset = 10;
|
||||
private const string DefaultTagType = "info";
|
||||
|
||||
public EnumToDictJob(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
@ -24,46 +24,54 @@ public class EnumToDictJob : IJob
|
||||
|
||||
public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
|
||||
{
|
||||
var originColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine($"【{DateTime.Now}】系统枚举转换字典");
|
||||
|
||||
using var serviceScope = _scopeFactory.CreateScope();
|
||||
var sysEnumService = serviceScope.ServiceProvider.GetRequiredService<SysEnumService>();
|
||||
// 获取数据库连接
|
||||
var db = serviceScope.ServiceProvider.GetRequiredService<ISqlSugarClient>().CopyNew();
|
||||
|
||||
var sysEnumService = serviceScope.ServiceProvider.GetRequiredService<SysEnumService>();
|
||||
var sysDictTypeList = GetDictByEnumType(sysEnumService.GetEnumTypeList());
|
||||
// 获取枚举类型列表
|
||||
var enumTypeList = sysEnumService.GetEnumTypeList();
|
||||
var enumCodeList = enumTypeList.Select(u => u.TypeName);
|
||||
// 查询数据库中已存在的枚举类型代码
|
||||
//var exp = Expressionable.Create<SysDictType, SingleColumnEntity<string>>().And((t1, t2) => t1.Code == t2.ColumnName).ToExpression();
|
||||
//var sysDictTypeList = await db.Queryable<SysDictType>().Includes(t1 => t1.Children).BulkListQuery(exp, enumCodeList, stoppingToken);
|
||||
var sysDictTypeList = await db.Queryable<SysDictType>().Includes(u => u.Children)
|
||||
.Where(u => enumCodeList.Contains(u.Code)).ToListAsync(stoppingToken);
|
||||
// 更新的枚举转换字典
|
||||
var updatedEnumCodes = sysDictTypeList.Select(u => u.Code);
|
||||
var updatedEnumType = enumTypeList.Where(u => updatedEnumCodes.Contains(u.TypeName)).ToList();
|
||||
var sysDictTypeDict = sysDictTypeList.ToDictionary(u => u.Code, u => u);
|
||||
var (updatedDictTypes, updatedDictDatas, newSysDictDatas) = GetUpdatedDicts(updatedEnumType, sysDictTypeDict);
|
||||
|
||||
// 校验枚举类命名规范,字典相关功能中需要通过后缀判断是否为枚举类型
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
foreach (var dictType in sysDictTypeList.Where(x => !x.Code.EndsWith("Enum")))
|
||||
Console.WriteLine($"【{DateTime.Now}】系统枚举转换字典的枚举类名称必须以Enum结尾: {dictType.Code} ({dictType.Name})");
|
||||
sysDictTypeList = sysDictTypeList.Where(x => x.Code.EndsWith("Enum")).ToList();
|
||||
// 新增的枚举转换字典
|
||||
var newEnumType = enumTypeList.Where(u => !updatedEnumCodes.Contains(u.TypeName)).ToList();
|
||||
var (newDictTypes, newDictDatas) = GetNewSysDicts(newEnumType);
|
||||
|
||||
await SyncEnumToDictInfoAsync(db, sysDictTypeList);
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
// 执行数据库操作
|
||||
try
|
||||
{
|
||||
await db.BeginTranAsync();
|
||||
var storageable1 = await db.Storageable(sysDictTypeList)
|
||||
.SplitUpdate(it => it.Any())
|
||||
.SplitInsert(_ => true)
|
||||
.ToStorageAsync();
|
||||
await storageable1.BulkCopyAsync();
|
||||
await storageable1.BulkUpdateAsync();
|
||||
|
||||
Console.WriteLine($"【{DateTime.Now}】系统枚举类转字典类型数据: 插入{storageable1.InsertList.Count}条, 更新{storageable1.UpdateList.Count}条, 共{storageable1.TotalList.Count}条。");
|
||||
if (updatedDictTypes.Count > 0)
|
||||
await db.Updateable(updatedDictTypes).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
var storageable2 = await db.Storageable(sysDictTypeList.SelectMany(u => u.Children).ToList())
|
||||
.WhereColumns(u => new { u.DictTypeId, u.Code })
|
||||
.SplitUpdate(u => u.Any())
|
||||
.SplitInsert(_ => true)
|
||||
.ToStorageAsync();
|
||||
await storageable2.BulkCopyAsync();
|
||||
await storageable2.BulkUpdateAsync(nameof(SysDictData.Value), nameof(SysDictData.Code), nameof(SysDictData.Name));
|
||||
if (updatedDictDatas.Count > 0)
|
||||
await db.Updateable(updatedDictDatas).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
Console.WriteLine($"【{DateTime.Now}】系统枚举项转字典值数据: 插入{storageable2.InsertList.Count}条, 更新{storageable2.UpdateList.Count}条, 共{storageable2.TotalList.Count}条。");
|
||||
if (newSysDictDatas.Count > 0)
|
||||
{
|
||||
foreach (var dd in newSysDictDatas)
|
||||
await db.Insertable(dd).ExecuteCommandAsync(stoppingToken);
|
||||
}
|
||||
|
||||
if (newDictTypes.Count > 0)
|
||||
await db.Insertable(newDictTypes).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
if (newDictDatas.Count > 0)
|
||||
{
|
||||
foreach (var dd in newDictDatas)
|
||||
await db.Insertable(dd).ExecuteCommandAsync(stoppingToken);
|
||||
}
|
||||
|
||||
await db.CommitTranAsync();
|
||||
}
|
||||
@ -73,63 +81,131 @@ public class EnumToDictJob : IJob
|
||||
Log.Error($"系统枚举转换字典操作错误:{error.Message}\n堆栈跟踪:{error.StackTrace}", error);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.ForegroundColor = originColor;
|
||||
}
|
||||
var originColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine($"【{DateTime.Now}】系统枚举转换字典");
|
||||
Console.ForegroundColor = originColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于同步枚举转字典旧数据(后期可删除)
|
||||
/// 获取需要新增的字典列表
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <param name="list"></param>
|
||||
//[Obsolete]
|
||||
private static async Task SyncEnumToDictInfoAsync(SqlSugarClient db, List<SysDictType> list)
|
||||
/// <param name="addEnumType"></param>
|
||||
/// <returns>
|
||||
/// 一个元组,包含以下元素:
|
||||
/// <list type="table">
|
||||
/// <item><term>SysDictTypes</term><description>字典类型列表</description></item>
|
||||
/// <item><term>SysDictDatas</term><description>字典数据列表</description></item>
|
||||
/// </list>
|
||||
/// </returns>
|
||||
private (List<SysDictType>, List<SysDictData>) GetNewSysDicts(List<EnumTypeOutput> addEnumType)
|
||||
{
|
||||
var codeList = list.Select(u => u.Code).ToList();
|
||||
foreach (var dbDictType in await db.Queryable<SysDictType>().Where(x => codeList.Contains(x.Code)).ToListAsync() ?? new())
|
||||
{
|
||||
var enumDictType = list.First(u => u.Code == dbDictType.Code);
|
||||
if (enumDictType.Id == dbDictType.Id) continue;
|
||||
var newDictType = new List<SysDictType>();
|
||||
var newDictData = new List<SysDictData>();
|
||||
if (addEnumType.Count <= 0)
|
||||
return (newDictType, newDictData);
|
||||
|
||||
// 数据不一致则删除
|
||||
_ = db.Deleteable<SysDictData>().Where(u => u.DictTypeId == dbDictType.Id).ExecuteCommandAsync();
|
||||
_ = db.Deleteable<SysDictType>().Where(u => u.Id == dbDictType.Id).ExecuteCommandAsync();
|
||||
Console.WriteLine($"【{DateTime.Now}】删除字典数据: {dbDictType.Name}-{dbDictType.Code}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 枚举信息转字典
|
||||
/// </summary>
|
||||
/// <param name="enumTypeList"></param>
|
||||
/// <returns></returns>
|
||||
private List<SysDictType> GetDictByEnumType(List<EnumTypeOutput> enumTypeList)
|
||||
{
|
||||
var orderNo = 1;
|
||||
var list = new List<SysDictType>();
|
||||
foreach (var type in enumTypeList)
|
||||
// 新增字典类型
|
||||
newDictType = addEnumType.Select(u => new SysDictType
|
||||
{
|
||||
var dictType = new SysDictType
|
||||
Id = YitIdHelper.NextId(),
|
||||
Code = u.TypeName,
|
||||
Name = u.TypeDescribe,
|
||||
Remark = u.TypeRemark,
|
||||
Status = StatusEnum.Enable
|
||||
}).ToList();
|
||||
|
||||
// 新增字典数据
|
||||
newDictData = addEnumType.Join(newDictType, t1 => t1.TypeName, t2 => t2.Code, (t1, t2) => new
|
||||
{
|
||||
Data = t1.EnumEntities.Select(u => new SysDictData
|
||||
{
|
||||
Id = 900000000000 + CommonUtil.GetFixedHashCode(type.TypeName),
|
||||
Code = type.TypeName,
|
||||
Name = type.TypeDescribe,
|
||||
Remark = type.TypeRemark
|
||||
};
|
||||
dictType.Children = type.EnumEntities.Select(u => new SysDictData
|
||||
{
|
||||
Id = dictType.Id + orderNo++,
|
||||
DictTypeId = dictType.Id,
|
||||
Name = u.Name,
|
||||
Value = u.Describe,
|
||||
Code = u.Value.ToString(),
|
||||
Id = YitIdHelper.NextId(),
|
||||
DictTypeId = t2.Id,
|
||||
Name = u.Describe,
|
||||
Value = u.Value.ToString(),
|
||||
Code = u.Name,
|
||||
Remark = t2.Remark,
|
||||
OrderNo = u.Value + OrderOffset,
|
||||
TagType = u.Theme != "" ? u.Theme : DefaultTagType,
|
||||
}).ToList();
|
||||
list.Add(dictType);
|
||||
}).ToList()
|
||||
}).SelectMany(x => x.Data).ToList();
|
||||
|
||||
return (newDictType, newDictData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取需要更新的字典列表
|
||||
/// </summary>
|
||||
/// <param name="updatedEnumType"></param>
|
||||
/// <param name="sysDictTypeDict"></param>
|
||||
/// <returns>
|
||||
/// 一个元组,包含以下元素:
|
||||
/// <list type="table">
|
||||
/// <item><term>SysDictTypes</term><description>更新字典类型列表</description>
|
||||
/// </item>
|
||||
/// <item><term>SysDictDatas</term><description>更新字典数据列表</description>
|
||||
/// </item>
|
||||
/// <item><term>SysDictDatas</term><description>新增字典数据列表</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </returns>
|
||||
private (List<SysDictType>, List<SysDictData>, List<SysDictData>) GetUpdatedDicts(List<EnumTypeOutput> updatedEnumType, Dictionary<string, SysDictType> sysDictTypeDict)
|
||||
{
|
||||
var updatedSysDictTypes = new List<SysDictType>();
|
||||
var updatedSysDictData = new List<SysDictData>();
|
||||
var newSysDictData = new List<SysDictData>();
|
||||
foreach (var e in updatedEnumType)
|
||||
{
|
||||
if (!sysDictTypeDict.TryGetValue(e.TypeName, out var value))
|
||||
continue;
|
||||
|
||||
var updatedDictType = value;
|
||||
updatedDictType.Name = e.TypeDescribe;
|
||||
updatedDictType.Remark = e.TypeRemark;
|
||||
updatedSysDictTypes.Add(updatedDictType);
|
||||
var updatedDictData = updatedDictType.Children.Where(u => u.DictTypeId == updatedDictType.Id).ToList();
|
||||
|
||||
// 遍历需要更新的字典数据
|
||||
foreach (var dictData in updatedDictData)
|
||||
{
|
||||
var enumData = e.EnumEntities.FirstOrDefault(u => dictData.Code == u.Name);
|
||||
if (enumData != null)
|
||||
{
|
||||
dictData.Value = enumData.Value.ToString();
|
||||
dictData.OrderNo = enumData.Value + OrderOffset;
|
||||
dictData.Name = enumData.Describe;
|
||||
dictData.TagType = enumData.Theme != "" ? enumData.Theme : dictData.TagType != "" ? dictData.TagType : DefaultTagType;
|
||||
updatedSysDictData.Add(dictData);
|
||||
}
|
||||
}
|
||||
|
||||
// 新增的枚举值名称列表
|
||||
var newEnumDataNameList = e.EnumEntities.Select(u => u.Name).Except(updatedDictData.Select(u => u.Code));
|
||||
foreach (var newEnumDataName in newEnumDataNameList)
|
||||
{
|
||||
var enumData = e.EnumEntities.FirstOrDefault(u => newEnumDataName == u.Name);
|
||||
if (enumData != null)
|
||||
{
|
||||
var dictData = new SysDictData
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
DictTypeId = updatedDictType.Id,
|
||||
Name = enumData.Describe,
|
||||
Value = enumData.Value.ToString(),
|
||||
Code = enumData.Name,
|
||||
Remark = updatedDictType.Remark,
|
||||
OrderNo = enumData.Value + OrderOffset,
|
||||
TagType = enumData.Theme != "" ? enumData.Theme : DefaultTagType,
|
||||
};
|
||||
dictData.TagType = enumData.Theme != "" ? enumData.Theme : dictData.TagType != "" ? dictData.TagType : DefaultTagType;
|
||||
newSysDictData.Add(dictData);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除的情况暂不处理
|
||||
}
|
||||
return list;
|
||||
|
||||
return (updatedSysDictTypes, updatedSysDictData, newSysDictData);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user