using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; using System.Text; using System.Threading.Tasks; using YiSha.Data; using YiSha.Data.EF; using YiSha.Data.Repository; using YiSha.Entity; using YiSha.Entity.OrganizationManage; using YiSha.Entity.SystemManage; using YiSha.Enum; using YiSha.IService.SystemManage; using YiSha.Model.Result.SystemManage; using YiSha.Util; using YiSha.Util.Model; namespace YiSha.Service.SystemManage { public partial class DatabaseTableMySqlService : IDatabaseTableMySqlService { private IRepositoryFactory _baseRepository; public DatabaseTableMySqlService(IRepositoryFactory baseRepository) { _baseRepository = baseRepository; } #region 获取数据 public async Task> GetTableList(string tableName, DBConnectTypeEnum dbConnectType) { StringBuilder strSql = new StringBuilder(); strSql.Append(@"SELECT table_name TableName FROM information_schema.tables WHERE table_schema='" + GetDatabase(dbConnectType) + "' AND table_type='base table'"); IEnumerable list = await _baseRepository.BaseRepository(dbConnectType).FindList(strSql.ToString()); if (!string.IsNullOrEmpty(tableName)) { list = list.Where(p => p.TableName.Contains(tableName)); } await SetTableDetail(dbConnectType, list); return list.ToList(); } public async Task> GetTablePageList(string tableName, DBConnectTypeEnum dbConnectType, Pagination pagination) { StringBuilder strSql = new StringBuilder(); var parameter = new List(); strSql.Append(@"SELECT table_name TableName FROM information_schema.tables where table_schema='" + GetDatabase(dbConnectType) + "' and (table_type='base table' or table_type='BASE TABLE')"); if (!string.IsNullOrEmpty(tableName)) { strSql.Append(" AND table_name like @TableName "); parameter.Add(DbParameterExtension.CreateDbParameter("@TableName", '%' + tableName + '%', dbConnectType)); } IEnumerable list = await _baseRepository.BaseRepository(dbConnectType).FindList(strSql.ToString(), parameter.ToArray(), pagination); await SetTableDetail(dbConnectType, list); return list.ToList(); } public async Task> GetTableFieldList(string tableName, DBConnectTypeEnum dbConnectType) { StringBuilder strSql = new StringBuilder(); strSql.Append(@"SELECT COLUMN_NAME TableColumn, DATA_TYPE Datatype, (CASE COLUMN_KEY WHEN 'PRI' THEN COLUMN_NAME ELSE '' END) TableIdentity, REPLACE(REPLACE(SUBSTRING(COLUMN_TYPE,LOCATE('(',COLUMN_TYPE)),'(',''),')','') FieldLength, (CASE IS_NULLABLE WHEN 'NO' THEN 'N' ELSE 'Y' END) IsNullable, IFNULL(COLUMN_DEFAULT,'') FieldDefault, COLUMN_COMMENT Remark FROM information_schema.columns WHERE table_schema='" + GetDatabase(dbConnectType) + "' AND table_name=@TableName"); var parameter = new List(); parameter.Add(DbParameterExtension.CreateDbParameter("@TableName", tableName, dbConnectType)); var list = await _baseRepository.BaseRepository(dbConnectType).FindList(strSql.ToString(), parameter.ToArray()); return list.ToList(); } #endregion #region 公有方法 public async Task DatabaseBackup(string database, string backupPath, DBConnectTypeEnum dbConnectType) { string backupFile = string.Format("{0}\\{1}_{2}.bak", backupPath, database, DateTime.Now.ToString("yyyyMMddHHmmss")); string strSql = string.Format(" backup database [{0}] to disk = '{1}'", database, backupFile); var result = await _baseRepository.BaseRepository(dbConnectType).ExecuteBySql(strSql); return result > 0 ? true : false; } /// /// 仅用在YiShaAdmin框架里面,同步不同数据库之间的数据,以 MySql 为主库,同步 MySql 的数据到SqlServer和Oracle,保证各个数据库的数据是一样的 /// /// public async Task SyncDatabase() { #region 同步SqlServer数据库 await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); await SyncSqlServerTable(); #endregion } private async Task SyncSqlServerTable() where T : class, new() { string sqlServerConnectionString = "Server=localhost;Database=YiShaAdmin;User Id=sa;Password=123456;"; IEnumerable list = await _baseRepository.BaseRepository(DBConnectTypeEnum.SystemDB).FindList(); await new SqlServerDatabase(sqlServerConnectionString).Delete(p => true); await new SqlServerDatabase(sqlServerConnectionString).Insert(list); } #endregion #region 私有方法 /// /// 获取所有表的主键、主键名称、记录数 /// /// /// /// private async Task> GetTableDetailList(DBConnectTypeEnum dbConnectType, IEnumerable list) { var tableSchema = GetDatabase(dbConnectType); string strSql = @"SELECT t1.TABLE_NAME TableName,t1.TABLE_COMMENT Remark,t1.TABLE_ROWS TableCount,t2.CONSTRAINT_NAME TableKeyName,t2.column_name TableKey FROM information_schema.TABLES as t1 LEFT JOIN INFORMATION_SCHEMA.`KEY_COLUMN_USAGE` as t2 on t1.TABLE_NAME = t2.TABLE_NAME WHERE t1.TABLE_SCHEMA='" + tableSchema + "' AND t2.TABLE_SCHEMA='" + tableSchema + "'"; if (list != null && list.Count() > 0) { strSql += " AND t1.TABLE_NAME in(" + string.Join(",", list.Select(p => "'" + p.TableName + "'")) + ")";//生成 Where In 条件 } IEnumerable result = await _baseRepository.BaseRepository(dbConnectType).FindList(strSql.ToString()); return result.ToList(); } /// /// 赋值表的主键、主键名称、记录数 /// /// /// private async Task SetTableDetail(DBConnectTypeEnum dbConnectType, IEnumerable list) { List detailList = await GetTableDetailList(dbConnectType, list); foreach (TableInfo table in list) { table.TableKey = string.Join(",", detailList.Where(p => p.TableName == table.TableName).Select(p => p.TableKey)); var tableInfo = detailList.Where(p => p.TableName == table.TableName).FirstOrDefault(); if (tableInfo != null) { table.TableKeyName = tableInfo.TableKeyName; table.TableCount = tableInfo.TableCount; table.Remark = tableInfo.Remark; } } } private string GetDatabase(DBConnectTypeEnum dbConnectType) { DBConnectHelper.GetInstance.GetDBConnectInfo(dbConnectType, out string dbType, out string dbConnectionString); if (dbType.ToLower() == "mysql") return HtmlHelper.Resove(dbConnectionString.ToLower(), "database=", ";"); else if (dbType.ToLower() == "sqlserver") return "dbo"; return ""; } #endregion } }