|
|
|
@ -1,643 +0,0 @@ |
|
|
|
|
using Newtonsoft.Json; |
|
|
|
|
using SqlSugar; |
|
|
|
|
using System.Diagnostics; |
|
|
|
|
using System.Reflection; |
|
|
|
|
using System.Text; |
|
|
|
|
using Tiobon.Core.Common.DB; |
|
|
|
|
using Tiobon.Core.Extensions; |
|
|
|
|
using Tiobon.Core.Const; |
|
|
|
|
using Tiobon.Core.DB; |
|
|
|
|
using Tiobon.Core.Helper; |
|
|
|
|
using Tiobon.Core.Model.Models; |
|
|
|
|
using Tiobon.Core.Model.Tenants; |
|
|
|
|
using Tiobon.Core.Model; |
|
|
|
|
|
|
|
|
|
namespace Tiobon.Core.Common.Seed; |
|
|
|
|
|
|
|
|
|
public class DBSeed |
|
|
|
|
{ |
|
|
|
|
private static string SeedDataFolder = "TiobonCore.Data.json/{0}.tsv"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 异步添加种子数据 |
|
|
|
|
/// </summary> |
|
|
|
|
/// <param name="myContext"></param> |
|
|
|
|
/// <param name="WebRootPath"></param> |
|
|
|
|
/// <returns></returns> |
|
|
|
|
public static async Task SeedAsync(MyContext myContext, string WebRootPath) |
|
|
|
|
{ |
|
|
|
|
try |
|
|
|
|
{ |
|
|
|
|
if (string.IsNullOrEmpty(WebRootPath)) |
|
|
|
|
{ |
|
|
|
|
throw new Exception("获取wwwroot路径时,异常!"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SeedDataFolder = Path.Combine(WebRootPath, SeedDataFolder); |
|
|
|
|
|
|
|
|
|
Console.WriteLine("************ Tiobon.Core DataBase Set *****************"); |
|
|
|
|
Console.WriteLine($"Master DB ConId: {myContext.Db.CurrentConnectionConfig.ConfigId}"); |
|
|
|
|
Console.WriteLine($"Master DB Type: {myContext.Db.CurrentConnectionConfig.DbType}"); |
|
|
|
|
Console.WriteLine($"Master DB ConnectString: {myContext.Db.CurrentConnectionConfig.ConnectionString}"); |
|
|
|
|
Console.WriteLine(); |
|
|
|
|
if (BaseDBConfig.MainConfig.SlaveConnectionConfigs.AnyNoException()) |
|
|
|
|
{ |
|
|
|
|
var index = 0; |
|
|
|
|
BaseDBConfig.MainConfig.SlaveConnectionConfigs.ForEach(m => |
|
|
|
|
{ |
|
|
|
|
index++; |
|
|
|
|
Console.WriteLine($"Slave{index} DB HitRate: {m.HitRate}"); |
|
|
|
|
Console.WriteLine($"Slave{index} DB ConnectString: {m.ConnectionString}"); |
|
|
|
|
Console.WriteLine($"--------------------------------------"); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
else if (BaseDBConfig.ReuseConfigs.AnyNoException()) |
|
|
|
|
{ |
|
|
|
|
var index = 0; |
|
|
|
|
BaseDBConfig.ReuseConfigs.ForEach(m => |
|
|
|
|
{ |
|
|
|
|
index++; |
|
|
|
|
Console.WriteLine($"Reuse{index} DB ID: {m.ConfigId}"); |
|
|
|
|
Console.WriteLine($"Reuse{index} DB Type: {m.DbType}"); |
|
|
|
|
Console.WriteLine($"Reuse{index} DB ConnectString: {m.ConnectionString}"); |
|
|
|
|
Console.WriteLine($"--------------------------------------"); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Console.WriteLine(); |
|
|
|
|
|
|
|
|
|
// 创建数据库 |
|
|
|
|
Console.WriteLine($"Create Database(The Db Id:{MyContext.ConnId})..."); |
|
|
|
|
|
|
|
|
|
if (MyContext.DbType != SqlSugar.DbType.Oracle && MyContext.DbType != SqlSugar.DbType.Dm) |
|
|
|
|
{ |
|
|
|
|
myContext.Db.DbMaintenance.CreateDatabase(); |
|
|
|
|
ConsoleHelper.WriteSuccessLine($"Database created successfully!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
//Oracle 数据库不支持该操作 |
|
|
|
|
ConsoleHelper.WriteSuccessLine($"Oracle 数据库不支持该操作,可手动创建Oracle/Dm数据库!"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 创建数据库表,遍历指定命名空间下的class, |
|
|
|
|
// 注意不要把其他命名空间下的也添加进来。 |
|
|
|
|
Console.WriteLine("Create Tables..."); |
|
|
|
|
|
|
|
|
|
var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; |
|
|
|
|
var referencedAssemblies = System.IO.Directory.GetFiles(path, "Tiobon.Core.Model.dll") |
|
|
|
|
.Select(Assembly.LoadFrom).ToArray(); |
|
|
|
|
var modelTypes = referencedAssemblies |
|
|
|
|
.SelectMany(a => a.DefinedTypes) |
|
|
|
|
.Select(type => type.AsType()) |
|
|
|
|
.Where(x => x.IsClass && x.Namespace is "Tiobon.Core.Model.Models") |
|
|
|
|
.Where(s => !s.IsDefined(typeof(MultiTenantAttribute), false)) |
|
|
|
|
.ToList(); |
|
|
|
|
modelTypes.ForEach(t => |
|
|
|
|
{ |
|
|
|
|
// 这里只支持添加表,不支持删除 |
|
|
|
|
// 如果想要删除,数据库直接右键删除,或者联系SqlSugar作者; |
|
|
|
|
if (!myContext.Db.DbMaintenance.IsAnyTable(t.Name)) |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine(t.Name); |
|
|
|
|
myContext.Db.CodeFirst.SplitTables().InitTables(t); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
ConsoleHelper.WriteSuccessLine($"Tables created successfully!"); |
|
|
|
|
Console.WriteLine(); |
|
|
|
|
|
|
|
|
|
if (AppSettings.app(new string[] { "AppSettings", "SeedDBDataEnabled" }).ObjToBool()) |
|
|
|
|
{ |
|
|
|
|
JsonSerializerSettings setting = new JsonSerializerSettings(); |
|
|
|
|
JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() => |
|
|
|
|
{ |
|
|
|
|
//日期类型默认格式化处理 |
|
|
|
|
setting.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; |
|
|
|
|
setting.DateFormatString = "yyyy-MM-dd HH:mm:ss"; |
|
|
|
|
|
|
|
|
|
//空值处理 |
|
|
|
|
setting.NullValueHandling = NullValueHandling.Ignore; |
|
|
|
|
|
|
|
|
|
//高级用法九中的Bool类型转换 设置 |
|
|
|
|
//setting.Converters.Add(new BoolConvert("是,否")); |
|
|
|
|
|
|
|
|
|
return setting; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
Console.WriteLine($"Seeding database data (The Db Id:{MyContext.ConnId})..."); |
|
|
|
|
|
|
|
|
|
//var importer = new ExcelImporter(); |
|
|
|
|
|
|
|
|
|
#region TiobonArticle |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<TiobonArticle>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
myContext.GetEntityDB<TiobonArticle>().InsertRange( |
|
|
|
|
JsonHelper.ParseFormByJson<List<TiobonArticle>>( |
|
|
|
|
FileHelper.ReadFile(string.Format(SeedDataFolder, "TiobonArticle"), Encoding.UTF8))); |
|
|
|
|
Console.WriteLine("Table:TiobonArticle created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:TiobonArticle already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Modules |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<Modules>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
var data = JsonConvert.DeserializeObject<List<Modules>>( |
|
|
|
|
FileHelper.ReadFile(string.Format(SeedDataFolder, "Modules"), Encoding.UTF8), setting); |
|
|
|
|
|
|
|
|
|
myContext.GetEntityDB<Modules>().InsertRange(data); |
|
|
|
|
Console.WriteLine("Table:Modules created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:Modules already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Permission |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<Permission>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
var data = JsonConvert.DeserializeObject<List<Permission>>( |
|
|
|
|
FileHelper.ReadFile(string.Format(SeedDataFolder, "Permission"), Encoding.UTF8), setting); |
|
|
|
|
|
|
|
|
|
myContext.GetEntityDB<Permission>().InsertRange(data); |
|
|
|
|
Console.WriteLine("Table:Permission created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:Permission already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Role |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<Role>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
var data = JsonConvert.DeserializeObject<List<Role>>( |
|
|
|
|
FileHelper.ReadFile(string.Format(SeedDataFolder, "Role"), Encoding.UTF8), setting); |
|
|
|
|
//using var stream = new FileStream(Path.Combine(WebRootPath, "TiobonCore.Data.excel", "Role.xlsx"), FileMode.Open); |
|
|
|
|
//var result = await importer.Import<Role>(stream); |
|
|
|
|
//var data = result.Data.ToList(); |
|
|
|
|
|
|
|
|
|
myContext.GetEntityDB<Role>().InsertRange(data); |
|
|
|
|
Console.WriteLine("Table:Role created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:Role already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region RoleModulePermission |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<RoleModulePermission>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
var data = JsonConvert.DeserializeObject<List<RoleModulePermission>>( |
|
|
|
|
FileHelper.ReadFile(string.Format(SeedDataFolder, "RoleModulePermission"), Encoding.UTF8), |
|
|
|
|
setting); |
|
|
|
|
|
|
|
|
|
myContext.GetEntityDB<RoleModulePermission>().InsertRange(data); |
|
|
|
|
Console.WriteLine("Table:RoleModulePermission created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:RoleModulePermission already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Topic |
|
|
|
|
|
|
|
|
|
//if (!await myContext.Db.Queryable<Topic>().AnyAsync()) |
|
|
|
|
//{ |
|
|
|
|
// var data = JsonConvert.DeserializeObject<List<Topic>>( |
|
|
|
|
// FileHelper.ReadFile(string.Format(SeedDataFolder, "Topic"), Encoding.UTF8), setting); |
|
|
|
|
|
|
|
|
|
// myContext.GetEntityDB<Topic>().InsertRange(data); |
|
|
|
|
// Console.WriteLine("Table:Topic created success!"); |
|
|
|
|
//} |
|
|
|
|
//else |
|
|
|
|
//{ |
|
|
|
|
// Console.WriteLine("Table:Topic already exists..."); |
|
|
|
|
//} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region TopicDetail |
|
|
|
|
|
|
|
|
|
//if (!await myContext.Db.Queryable<TopicDetail>().AnyAsync()) |
|
|
|
|
//{ |
|
|
|
|
// var data = JsonConvert.DeserializeObject<List<TopicDetail>>( |
|
|
|
|
// FileHelper.ReadFile(string.Format(SeedDataFolder, "TopicDetail"), Encoding.UTF8), setting); |
|
|
|
|
|
|
|
|
|
// myContext.GetEntityDB<TopicDetail>().InsertRange(data); |
|
|
|
|
// Console.WriteLine("Table:TopicDetail created success!"); |
|
|
|
|
//} |
|
|
|
|
//else |
|
|
|
|
//{ |
|
|
|
|
// Console.WriteLine("Table:TopicDetail already exists..."); |
|
|
|
|
//} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region UserRole |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<UserRole>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
var data = JsonConvert.DeserializeObject<List<UserRole>>( |
|
|
|
|
FileHelper.ReadFile(string.Format(SeedDataFolder, "UserRole"), Encoding.UTF8), setting); |
|
|
|
|
|
|
|
|
|
myContext.GetEntityDB<UserRole>().InsertRange(data); |
|
|
|
|
Console.WriteLine("Table:UserRole created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:UserRole already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region sysUserInfo |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<SysUserInfo>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
var data = JsonConvert.DeserializeObject<List<SysUserInfo>>( |
|
|
|
|
FileHelper.ReadFile(string.Format(SeedDataFolder, "sysUserInfo"), Encoding.UTF8), setting); |
|
|
|
|
|
|
|
|
|
myContext.GetEntityDB<SysUserInfo>().InsertRange(data); |
|
|
|
|
Console.WriteLine("Table:sysUserInfo created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:sysUserInfo already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region TasksQz |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<Ghre_TasksQz>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
var data = JsonConvert.DeserializeObject<List<Ghre_TasksQz>>( |
|
|
|
|
FileHelper.ReadFile(string.Format(SeedDataFolder, "TasksQz"), Encoding.UTF8), setting); |
|
|
|
|
|
|
|
|
|
myContext.GetEntityDB<Ghre_TasksQz>().InsertRange(data); |
|
|
|
|
Console.WriteLine("Table:TasksQz created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:TasksQz already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
#region TasksLog |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<Ghre_TasksLog>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:TasksLog created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:TasksLog already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
#region Department |
|
|
|
|
|
|
|
|
|
if (!await myContext.Db.Queryable<Department>().AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
var data = JsonConvert.DeserializeObject<List<Department>>( |
|
|
|
|
FileHelper.ReadFile(string.Format(SeedDataFolder, "Department"), Encoding.UTF8), setting); |
|
|
|
|
|
|
|
|
|
myContext.GetEntityDB<Department>().InsertRange(data); |
|
|
|
|
Console.WriteLine("Table:Department created success!"); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine("Table:Department already exists..."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
//种子初始化 |
|
|
|
|
await SeedDataAsync(myContext.Db); |
|
|
|
|
|
|
|
|
|
ConsoleHelper.WriteSuccessLine($"Done seeding database!"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Console.WriteLine(); |
|
|
|
|
} |
|
|
|
|
catch (Exception ex) |
|
|
|
|
{ |
|
|
|
|
throw new Exception( |
|
|
|
|
$"1、若是Mysql,查看常见问题:https://github.com/anjoy8/Tiobon.Core/issues/148#issue-776281770 \n" + |
|
|
|
|
$"2、若是Oracle,查看常见问题:https://github.com/anjoy8/Tiobon.Core/issues/148#issuecomment-752340231 \n" + |
|
|
|
|
"3、其他错误:" + ex.Message); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 种子初始化数据 |
|
|
|
|
/// </summary> |
|
|
|
|
/// <param name="myContext"></param> |
|
|
|
|
/// <returns></returns> |
|
|
|
|
private static async Task SeedDataAsync(ISqlSugarClient db) |
|
|
|
|
{ |
|
|
|
|
// 获取所有种子配置-初始化数据 |
|
|
|
|
var seedDataTypes = AssemblysExtensions.GetAllAssemblies().SelectMany(s => s.DefinedTypes) |
|
|
|
|
.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass) |
|
|
|
|
.Where(u => |
|
|
|
|
{ |
|
|
|
|
var esd = u.GetInterfaces() |
|
|
|
|
.FirstOrDefault(i => i.HasImplementedRawGeneric(typeof(IEntitySeedData<>))); |
|
|
|
|
if (esd is null) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var eType = esd.GenericTypeArguments[0]; |
|
|
|
|
if (eType.GetCustomAttribute<MultiTenantAttribute>() is null) |
|
|
|
|
{ |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
if (!seedDataTypes.Any()) return; |
|
|
|
|
foreach (var seedType in seedDataTypes) |
|
|
|
|
{ |
|
|
|
|
dynamic instance = Activator.CreateInstance(seedType); |
|
|
|
|
//初始化数据 |
|
|
|
|
{ |
|
|
|
|
var seedData = instance.InitSeedData(); |
|
|
|
|
if (seedData != null && Enumerable.Any(seedData)) |
|
|
|
|
{ |
|
|
|
|
var entityType = seedType.GetInterfaces().First().GetGenericArguments().First(); |
|
|
|
|
var entity = db.EntityMaintenance.GetEntityInfo(entityType); |
|
|
|
|
|
|
|
|
|
if (!await db.Queryable(entity.DbTableName, "").AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
await db.Insertable(Enumerable.ToList(seedData)).ExecuteCommandAsync(); |
|
|
|
|
Console.WriteLine($"Table:{entity.DbTableName} init success!"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//种子数据 |
|
|
|
|
{ |
|
|
|
|
var seedData = instance.SeedData(); |
|
|
|
|
if (seedData != null && Enumerable.Any(seedData)) |
|
|
|
|
{ |
|
|
|
|
var entityType = seedType.GetInterfaces().First().GetGenericArguments().First(); |
|
|
|
|
var entity = db.EntityMaintenance.GetEntityInfo(entityType); |
|
|
|
|
|
|
|
|
|
await db.Storageable(Enumerable.ToList(seedData)).ExecuteCommandAsync(); |
|
|
|
|
Console.WriteLine($"Table:{entity.DbTableName} seedData success!"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//自定义处理 |
|
|
|
|
{ |
|
|
|
|
await instance.CustomizeSeedData(db); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 迁移日志数据库 |
|
|
|
|
/// </summary> |
|
|
|
|
/// <returns></returns> |
|
|
|
|
public static void MigrationLogs(MyContext myContext) |
|
|
|
|
{ |
|
|
|
|
// 创建数据库表,遍历指定命名空间下的class, |
|
|
|
|
// 注意不要把其他命名空间下的也添加进来。 |
|
|
|
|
Console.WriteLine("Create Log Tables..."); |
|
|
|
|
if (!myContext.Db.IsAnyConnection(SqlSugarConst.LogConfigId.ToLower())) |
|
|
|
|
{ |
|
|
|
|
throw new ApplicationException("未配置日志数据库,请在appsettings.json中DBS节点中配置"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var logDb = myContext.Db.GetConnection(SqlSugarConst.LogConfigId.ToLower()); |
|
|
|
|
Console.WriteLine($"Create log Database(The Db Id:{SqlSugarConst.LogConfigId.ToLower()})..."); |
|
|
|
|
logDb.DbMaintenance.CreateDatabase(); |
|
|
|
|
ConsoleHelper.WriteSuccessLine($"Log Database created successfully!"); |
|
|
|
|
var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; |
|
|
|
|
var referencedAssemblies = System.IO.Directory.GetFiles(path, "Tiobon.Core.Model.dll") |
|
|
|
|
.Select(Assembly.LoadFrom).ToArray(); |
|
|
|
|
var modelTypes = referencedAssemblies |
|
|
|
|
.SelectMany(a => a.DefinedTypes) |
|
|
|
|
.Select(type => type.AsType()) |
|
|
|
|
.Where(x => x.IsClass && x.Namespace != null && x.Namespace.StartsWith("Tiobon.Core.Model.Logs")) |
|
|
|
|
.ToList(); |
|
|
|
|
Stopwatch sw = Stopwatch.StartNew(); |
|
|
|
|
|
|
|
|
|
var tables = logDb.DbMaintenance.GetTableInfoList(); |
|
|
|
|
|
|
|
|
|
modelTypes.ForEach(t => |
|
|
|
|
{ |
|
|
|
|
// 这里只支持添加修改表,不支持删除 |
|
|
|
|
// 如果想要删除,数据库直接右键删除,或者联系SqlSugar作者; |
|
|
|
|
if (!tables.Any(s => s.Name.Contains(t.Name))) |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine(t.Name); |
|
|
|
|
if (t.GetCustomAttribute<SplitTableAttribute>() != null) |
|
|
|
|
{ |
|
|
|
|
logDb.CodeFirst.SplitTables().InitTables(t); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
logDb.CodeFirst.InitTables(t); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
sw.Stop(); |
|
|
|
|
|
|
|
|
|
$"Log Tables created successfully! {sw.ElapsedMilliseconds}ms".WriteSuccessLine(); |
|
|
|
|
Console.WriteLine(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 初始化 多租户 |
|
|
|
|
/// </summary> |
|
|
|
|
/// <param name="myContext"></param> |
|
|
|
|
/// <returns></returns> |
|
|
|
|
public static async Task TenantSeedAsync(MyContext myContext) |
|
|
|
|
{ |
|
|
|
|
var tenants = await myContext.Db.Queryable<SysTenant>().Where(s => s.TenantType == TenantTypeEnum.Db) |
|
|
|
|
.ToListAsync(); |
|
|
|
|
if (tenants.Any()) |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine($@"Init Multi Tenant Db"); |
|
|
|
|
foreach (var tenant in tenants) |
|
|
|
|
{ |
|
|
|
|
Console.WriteLine($@"Init Multi Tenant Db : {tenant.ConfigId}/{tenant.Name}"); |
|
|
|
|
await InitTenantSeedAsync(myContext.Db.AsTenant(), tenant.GetConnectionConfig()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tenants = await myContext.Db.Queryable<SysTenant>().Where(s => s.TenantType == TenantTypeEnum.Tables) |
|
|
|
|
.ToListAsync(); |
|
|
|
|
if (tenants.Any()) |
|
|
|
|
{ |
|
|
|
|
await InitTenantSeedAsync(myContext, tenants); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#region 多租户 多表 初始化 |
|
|
|
|
|
|
|
|
|
private static async Task InitTenantSeedAsync(MyContext myContext, List<SysTenant> tenants) |
|
|
|
|
{ |
|
|
|
|
ConsoleHelper.WriteInfoLine($"Init Multi Tenant Tables : {myContext.Db.CurrentConnectionConfig.ConfigId}"); |
|
|
|
|
|
|
|
|
|
// 获取所有实体表-初始化租户业务表 |
|
|
|
|
var entityTypes = TenantUtil.GetTenantEntityTypes(TenantTypeEnum.Tables); |
|
|
|
|
if (!entityTypes.Any()) return; |
|
|
|
|
|
|
|
|
|
foreach (var sysTenant in tenants) |
|
|
|
|
{ |
|
|
|
|
foreach (var entityType in entityTypes) |
|
|
|
|
{ |
|
|
|
|
myContext.Db.CodeFirst |
|
|
|
|
.As(entityType, entityType.GetTenantTableName(myContext.Db, sysTenant)) |
|
|
|
|
.InitTables(entityType); |
|
|
|
|
|
|
|
|
|
Console.WriteLine($@"Init Tables:{entityType.GetTenantTableName(myContext.Db, sysTenant)}"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
myContext.Db.SetTenantTable(sysTenant.Id.ToString()); |
|
|
|
|
//多租户初始化种子数据 |
|
|
|
|
await TenantSeedDataAsync(myContext.Db, TenantTypeEnum.Tables); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ConsoleHelper.WriteSuccessLine( |
|
|
|
|
$"Init Multi Tenant Tables : {myContext.Db.CurrentConnectionConfig.ConfigId} created successfully!"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
#region 多租户 多库 初始化 |
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
/// 初始化多库 |
|
|
|
|
/// </summary> |
|
|
|
|
/// <param name="itenant"></param> |
|
|
|
|
/// <param name="config"></param> |
|
|
|
|
/// <returns></returns> |
|
|
|
|
public static async Task InitTenantSeedAsync(ITenant itenant, ConnectionConfig config) |
|
|
|
|
{ |
|
|
|
|
itenant.RemoveConnection(config.ConfigId); |
|
|
|
|
itenant.AddConnection(config); |
|
|
|
|
|
|
|
|
|
var db = itenant.GetConnectionScope(config.ConfigId); |
|
|
|
|
|
|
|
|
|
db.DbMaintenance.CreateDatabase(); |
|
|
|
|
ConsoleHelper.WriteSuccessLine($"Init Multi Tenant Db : {config.ConfigId} Database created successfully!"); |
|
|
|
|
|
|
|
|
|
Console.WriteLine($@"Init Multi Tenant Db : {config.ConfigId} Create Tables"); |
|
|
|
|
|
|
|
|
|
// 获取所有实体表-初始化租户业务表 |
|
|
|
|
var entityTypes = TenantUtil.GetTenantEntityTypes(TenantTypeEnum.Db); |
|
|
|
|
if (!entityTypes.Any()) return; |
|
|
|
|
foreach (var entityType in entityTypes) |
|
|
|
|
{ |
|
|
|
|
var splitTable = entityType.GetCustomAttribute<SplitTableAttribute>(); |
|
|
|
|
if (splitTable == null) |
|
|
|
|
db.CodeFirst.InitTables(entityType); |
|
|
|
|
else |
|
|
|
|
db.CodeFirst.SplitTables().InitTables(entityType); |
|
|
|
|
|
|
|
|
|
Console.WriteLine(entityType.Name); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//多租户初始化种子数据 |
|
|
|
|
await TenantSeedDataAsync(db, TenantTypeEnum.Db); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
#region 多租户 种子数据 初始化 |
|
|
|
|
|
|
|
|
|
private static async Task TenantSeedDataAsync(ISqlSugarClient db, TenantTypeEnum tenantType) |
|
|
|
|
{ |
|
|
|
|
// 获取所有种子配置-初始化数据 |
|
|
|
|
var seedDataTypes = AssemblysExtensions.GetAllAssemblies().SelectMany(s => s.DefinedTypes) |
|
|
|
|
.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass) |
|
|
|
|
.Where(u => |
|
|
|
|
{ |
|
|
|
|
var esd = u.GetInterfaces() |
|
|
|
|
.FirstOrDefault(i => i.HasImplementedRawGeneric(typeof(IEntitySeedData<>))); |
|
|
|
|
if (esd is null) |
|
|
|
|
{ |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var eType = esd.GenericTypeArguments[0]; |
|
|
|
|
return eType.IsTenantEntity(tenantType); |
|
|
|
|
}); |
|
|
|
|
if (!seedDataTypes.Any()) return; |
|
|
|
|
foreach (var seedType in seedDataTypes) |
|
|
|
|
{ |
|
|
|
|
dynamic instance = Activator.CreateInstance(seedType); |
|
|
|
|
//初始化数据 |
|
|
|
|
{ |
|
|
|
|
var seedData = instance.InitSeedData(); |
|
|
|
|
if (seedData != null && Enumerable.Any(seedData)) |
|
|
|
|
{ |
|
|
|
|
var entityType = seedType.GetInterfaces().First().GetGenericArguments().First(); |
|
|
|
|
var entity = db.EntityMaintenance.GetEntityInfo(entityType); |
|
|
|
|
|
|
|
|
|
if (!await db.Queryable(entity.DbTableName, "").AnyAsync()) |
|
|
|
|
{ |
|
|
|
|
await db.Insertable(Enumerable.ToList(seedData)).ExecuteCommandAsync(); |
|
|
|
|
Console.WriteLine($"Table:{entity.DbTableName} init success!"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//种子数据 |
|
|
|
|
{ |
|
|
|
|
var seedData = instance.SeedData(); |
|
|
|
|
if (seedData != null && Enumerable.Any(seedData)) |
|
|
|
|
{ |
|
|
|
|
var entityType = seedType.GetInterfaces().First().GetGenericArguments().First(); |
|
|
|
|
var entity = db.EntityMaintenance.GetEntityInfo(entityType); |
|
|
|
|
|
|
|
|
|
await db.Storageable(Enumerable.ToList(seedData)).ExecuteCommandAsync(); |
|
|
|
|
Console.WriteLine($"Table:{entity.DbTableName} seedData success!"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//自定义处理 |
|
|
|
|
{ |
|
|
|
|
await instance.CustomizeSeedData(db); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
|
} |