Merge pull request '增加初始化表结构时的重复检验' (#170) from x4689221/Admin.NET.Pro:main into main

Reviewed-on: http://101.43.53.74:3000/Admin.NET/Admin.NET.Pro/pulls/170
This commit is contained in:
zuohuaijun 2024-11-05 19:11:48 +08:00
commit 7fec044b16

View File

@ -4,8 +4,11 @@
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Newtonsoft.Json;
using System.Security.Cryptography;
namespace Admin.NET.Core;
public static class SqlSugarSetup
{
// 多租户实例
@ -335,14 +338,17 @@ public static class SqlSugarSetup
entityTypes = entityTypes.Where(u => u.GetCustomAttribute<TenantAttribute>()?.configId.ToString() == config.ConfigId.ToString()).ToList(); // 自定义的库
int count = 0, sum = entityTypes.Count;
foreach (var entityType in entityTypes)
TableUpdateCheck.Single(config.ConnectionString, entityTypes).TryUpdate(() =>
{
Console.WriteLine($"创建表 {entityType} ({config.ConfigId} - {++count}/{sum})");
if (entityType.GetCustomAttribute<SplitTableAttribute>() == null)
dbProvider.CodeFirst.InitTables(entityType);
else
dbProvider.CodeFirst.SplitTables().InitTables(entityType);
}
foreach (var entityType in entityTypes)
{
Console.WriteLine($"创建表 {entityType} ({config.ConfigId} - {++count}/{sum})");
if (entityType.GetCustomAttribute<SplitTableAttribute>() == null)
dbProvider.CodeFirst.InitTables(entityType);
else
dbProvider.CodeFirst.SplitTables().InitTables(entityType);
}
});
}
// 初始化种子数据
@ -539,4 +545,124 @@ public static class SqlSugarSetup
}
}
}
}
}
public class TableUpdateCheck
{
public TableUpdateCheck(string sqlConnectionStr = null, List<Type> tableList = null)
{
this._sqlConnectionStr = sqlConnectionStr;
this._tableList = tableList ?? new List<Type>();
}
public string TableName { get; set; }
public List<Attribute> AttributeList { get; set; } = new List<Attribute>();
public List<TableInfColumnM> ColumnList = new List<TableInfColumnM>();
public class TableInfColumnM
{
public string ColumnName { get; set; }
public List<Attribute> AttributeList { get; set; } = new List<Attribute>();
}
[JsonIgnore] public List<TableUpdateCheck> ConfigList { get; set; } = new List<TableUpdateCheck>();
[JsonIgnore] private string _sqlConnectionStr;
[JsonIgnore] private string _configFilePath = null;
[JsonIgnore]
public string ConfigFilePath => _configFilePath ??= _configFilePath =
Path.Combine(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase, @"TableHash\" + calculateHasByStr(calculateHasByStr(_sqlConnectionStr) + "0a") + ".bin");
[JsonIgnore] private List<Type> _tableList { get; set; } = null;
[JsonIgnore] private string _tableHashStr;
[JsonIgnore] public string TableHashStr => _tableHashStr ??= _tableHashStr = _tableList.Select(t => Parse(t).ToHash()).Aggregate((a, b) => a + "," + b);
public bool TryUpdate(Action updateAction)
{
if (CheckUpdateTable())
{
updateAction?.Invoke();
UpdateTableFinish();
return true;
}
return false;
}
public void UpdateTableFinish()
{
Directory.CreateDirectory(Path.GetDirectoryName(ConfigFilePath));
File.WriteAllText(ConfigFilePath, TableHashStr);
}
public bool CheckUpdateTable()
{
try
{
if (!File.Exists(ConfigFilePath))
{
return true;
}
var oldHashStr = File.ReadAllText(ConfigFilePath);
if (oldHashStr != TableHashStr)
{
return true;
}
return false;
}
catch (Exception e)
{
return true;
}
}
public static TableUpdateCheck Parse(Type type)
{
TableUpdateCheck table = new TableUpdateCheck() { TableName = type.FullName };
table.AttributeList = type.GetAttributes<Attribute>(true).ToList();
var propertyList = type.GetProperties().Where(t => t.PropertyType.IsPrimitive || t.PropertyType == typeof(string)).ToList();
table.ColumnList = propertyList.Select(t => new TableInfColumnM()
{
ColumnName = t.Name + t.PropertyType.Name,
AttributeList = t.GetAttributes<Attribute>(true).ToList(),
}).ToList();
return table;
}
public static TableUpdateCheck Single(string sqlConnectionStr, List<Type> tableList) => new TableUpdateCheck(sqlConnectionStr, tableList);
public static void CheckUpdateTableFinish(string sqlConnectionStr, IEnumerable<Type> types)
{
var basePath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
string filePath = Path.Combine(basePath, @"TableHash\" + calculateHasByStr(calculateHasByStr(sqlConnectionStr) + "0a") + ".bin");
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
var newHashStr = types.Select(t => Parse(t).ToHash()).Aggregate((a, b) => a + "," + b);
File.WriteAllText(filePath, newHashStr);
}
public string ToHash()
{
var js = JsonConvert.SerializeObject(this);
var md5 = calculateHasByStr(js);
return md5;
}
private static string calculateHasByStr(string str)
{
using (MD5 md5 = MD5.Create())
{
byte[] inputBytes = Encoding.UTF8.GetBytes(str);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// 将字节数组转换为十六进制字符串表示的哈希值
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("x2"));
}
string hash = sb.ToString();
return hash;
}
}
}