using System; using System.IO; using System.Linq; using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using FreeSql; using FreeSql.Aop; using FreeSql.DataAnnotations; using Admin.Core.Common.Configs; using Admin.Core.Common.Helpers; using Admin.Core.Model.Admin; namespace Admin.Core.Db { public class TenantDbHelper { /// /// 创建数据库 /// /// /// public async static Task CreateDatabase(DbConfig dbConfig) { if (!dbConfig.CreateDb || dbConfig.Type == DataType.Sqlite) { return; } var db = new FreeSqlBuilder() .UseConnectionString(dbConfig.Type, dbConfig.CreateDbConnectionString) .Build(); try { Console.WriteLine("\r\ncreate database started"); await db.Ado.ExecuteNonQueryAsync(dbConfig.CreateDbSql); Console.WriteLine("create database succeed\r\n"); } catch (Exception e) { Console.WriteLine($"create database failed.\n{e.Message}\r\n"); } } /// /// 同步结构 /// public static void SyncStructure(IFreeSql db, string msg = null, DbConfig dbConfig = null) { //打印结构比对脚本 //var dDL = db.CodeFirst.GetComparisonDDLStatements(); //Console.WriteLine("\r\n" + dDL); //打印结构同步脚本 //db.Aop.SyncStructureAfter += (s, e) => //{ // if (e.Sql.NotNull()) // { // Console.WriteLine("sync structure sql:\n" + e.Sql); // } //}; // 同步结构 var dbType = dbConfig.Type.ToString(); Console.WriteLine($"{(msg.NotNull() ? msg : $"sync {dbType} structure")} started"); if(dbConfig.Type == DataType.Oracle) { db.CodeFirst.IsSyncStructureToUpper = true; } db.CodeFirst.SyncStructure(new Type[] { typeof(DictionaryEntity), typeof(ApiEntity), typeof(ViewEntity), typeof(PermissionEntity), typeof(UserEntity), typeof(RoleEntity), typeof(UserRoleEntity), typeof(RolePermissionEntity), typeof(OprationLogEntity), typeof(LoginLogEntity), typeof(DocumentEntity), typeof(DocumentImageEntity) }); Console.WriteLine($"{(msg.NotNull() ? msg : $"sync {dbType} structure")} succeed\r\n"); } /// /// 初始化数据表数据 /// /// /// /// /// /// /// private static async Task InitDtData( IFreeSql db, T[] data, System.Data.Common.DbTransaction tran, DbConfig dbConfig = null ) where T : class { var table = typeof(T).GetCustomAttributes(typeof(TableAttribute),false).FirstOrDefault() as TableAttribute; var tableName = table.Name; try { if (!await db.Queryable().AnyAsync()) { if (data?.Length > 0) { var insert = db.Insert(); if(tran != null) { insert = insert.WithTransaction(tran); } if(dbConfig.Type == DataType.SqlServer) { var insrtSql = insert.AppendData(data).InsertIdentity().ToSql(); await db.Ado.ExecuteNonQueryAsync($"SET IDENTITY_INSERT {tableName} ON\n {insrtSql} \nSET IDENTITY_INSERT {tableName} OFF"); } else { await insert.AppendData(data).InsertIdentity().ExecuteAffrowsAsync(); } Console.WriteLine($"table: {tableName} sync data succeed"); } else { Console.WriteLine($"table: {tableName} import data []"); } } else { Console.WriteLine($"table: {tableName} record already exists"); } } catch (Exception ex) { Console.WriteLine($"table: {tableName} sync data failed.\n{ex.Message}"); } } /// /// 同步数据审计方法 /// /// /// private static void SyncDataAuditValue(object s, AuditValueEventArgs e) { if (e.AuditValueType == AuditValueType.Insert) { switch (e.Property.Name) { case "CreatedUserId": e.Value = 2; break; case "CreatedUserName": e.Value = "admin"; break; } } else if (e.AuditValueType == AuditValueType.Update) { switch (e.Property.Name) { case "ModifiedUserId": e.Value = 2; break; case "ModifiedUserName": e.Value = "admin"; break; } } } /// /// 同步数据 /// /// public static async Task SyncData(IFreeSql db, DbConfig dbConfig = null) { try { //db.Aop.CurdBefore += (s, e) => //{ // Console.WriteLine($"{e.Sql}\r\n"); //}; Console.WriteLine("sync data started"); db.Aop.AuditValue += SyncDataAuditValue; var filePath = Path.Combine(AppContext.BaseDirectory, "Db/Data/data.json").ToPath(); var jsonData = FileHelper.ReadFile(filePath); var data = JsonConvert.DeserializeObject(jsonData); using (var uow = db.CreateUnitOfWork()) using (var tran = uow.GetOrBeginTransaction()) { await InitDtData(db, data.Dictionaries, tran, dbConfig); await InitDtData(db, data.Apis, tran, dbConfig); await InitDtData(db, data.Views, tran, dbConfig); await InitDtData(db, data.Permissions, tran, dbConfig); await InitDtData(db, data.Users, tran, dbConfig); await InitDtData(db, data.Roles, tran, dbConfig); await InitDtData(db, data.UserRoles, tran, dbConfig); await InitDtData(db, data.RolePermissions, tran, dbConfig); uow.Commit(); } db.Aop.AuditValue -= SyncDataAuditValue; Console.WriteLine("sync data succeed\r\n"); } catch (Exception ex) { throw new Exception($"sync data failed.\n{ex.Message}\r\n"); } } /// /// 生成极简数据 /// /// /// public static async Task GenerateSimpleJsonData(IFreeSql db) { try { Console.WriteLine("\r\ngenerate data started"); #region 数据表 #region 数据字典 var dictionaries = await db.Queryable().ToListAsync(a => new { a.Id, a.ParentId, a.Name, a.Code, a.Value, a.Description, a.Sort }); #endregion #region 接口 var apis = await db.Queryable().ToListAsync(a => new { a.Id, a.ParentId, a.Name, a.Label, a.Path, a.HttpMethods, a.Description, a.Sort }); #endregion #region 视图 var views = await db.Queryable().ToListAsync(a => new { a.Id, a.ParentId, a.Name, a.Label, a.Path, a.Description, a.Sort }); #endregion #region 权限 var permissions = await db.Queryable().ToListAsync(a => new { a.Id, a.ParentId, a.Label, a.Code, a.Type, a.ViewId, a.ApiId, a.Path, a.Icon, a.Closable, a.Opened, a.NewWindow, a.External, a.Sort, a.Description }); #endregion #region 用户 var users = await db.Queryable().ToListAsync(a => new { a.Id, a.UserName, a.Password, a.NickName, a.Avatar, a.Status, a.Remark }); #endregion #region 角色 var roles = await db.Queryable().ToListAsync(a => new { a.Id, a.Name, a.Sort, a.Description }); #endregion #region 用户角色 var userRoles = await db.Queryable().ToListAsync(a => new { a.Id, a.UserId, a.RoleId }); #endregion #region 角色权限 var rolePermissions = await db.Queryable().ToListAsync(a => new { a.Id, a.RoleId, a.PermissionId }); #endregion #endregion if(!(users?.Count > 0)) { return; } #region 生成数据 var settings = new JsonSerializerSettings(); settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); settings.NullValueHandling = NullValueHandling.Ignore; settings.DefaultValueHandling = DefaultValueHandling.Ignore; var jsonData = JsonConvert.SerializeObject(new { dictionaries, apis, views, permissions, users, roles, userRoles, rolePermissions }, //Formatting.Indented, settings ); var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Db/Data/data.json").ToPath(); FileHelper.WriteFile(filePath, jsonData); #endregion Console.WriteLine("generate data succeed\r\n"); } catch (Exception ex) { throw new Exception($"generate data failed。\n{ex.Message}\r\n"); } } } }