using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Dapper; using Repository.Helper; using Repository.Models; using Repository.BaseRepository.Interface; using System.Reflection; using System.Data; using System.Text; using System.Data.SqlClient; using MySql.Data.MySqlClient; using Repository.Services.Implement; namespace Repository.BaseRepository.Implement { public class BaseRepository : IBaseRepository { protected readonly IDatabaseHelper _databaseHelper; protected string UseDB; protected IDbConnection con; private BackgroundService backgroundService; //排除要加入至派送的資料表 private List exclude_data_delivery = new List() { "background_service_message_notification_task", "background_service_message_notification_task_log", "background_service_plan", "background_service_task", "background_service_task_log", "device_import_temp", "device_import_ckeck_temp", "operation_back_log", "operation_log", "task_detail", "api_earthquake", "api_rain", "api_sync", "api_typhoon", "api_weateher", "archive_electric_meter_day", "archive_electric_meter_hour", "archive_electric_meter_month", "archive_electric_meter_week" }; public BaseRepository(IDatabaseHelper databaseHelper) { this._databaseHelper = databaseHelper; } public IDbConnection GetDbConnection() { IDbConnection conn; if (UseDB == "MSSQL") { conn = new SqlConnection(this._databaseHelper.GetMSSqlConnectionString()); } else { conn = new MySqlConnection(this._databaseHelper.GetMySqlConnectionString()); } return conn; } public string InsertGenerateString(List properties, string table_name) { var insertQuery = new StringBuilder($"INSERT INTO {table_name} "); insertQuery.Append("("); properties.ForEach(prop => { insertQuery.Append($"{table_name}.{prop.Replace("@", "")},"); }); insertQuery .Remove(insertQuery.Length - 1, 1) .Append(") VALUES ("); properties.ForEach(prop => { insertQuery.Append($"{prop},"); }); insertQuery .Remove(insertQuery.Length - 1, 1) .Append(");"); return insertQuery.ToString(); } public string UpdateGenerateString(List properties, string table_name, string sWhere) { var updateQuery = new StringBuilder($"UPDATE {table_name} SET "); properties.ForEach(property => { if (property.Contains("@")) { updateQuery.Append($"{property.Replace("@", "")}={property},"); } }); updateQuery.Remove(updateQuery.Length - 1, 1); //remove last comma updateQuery.Append($" WHERE {sWhere}"); return updateQuery.ToString(); } #region GetAll /// /// 取得所有資料(根據條件以及排序) /// /// /// /// /// Ex: new { status = 1} /// public virtual async Task> GetAllAsync(string tableName, string sWhere, object param = null, string sOrderBy = "") { List result; using (IDbConnection conn = GetDbConnection()) { try { var sql = $"SELECT * FROM {tableName}"; if (!string.IsNullOrEmpty(sWhere)) { sql += $" WHERE {sWhere}"; } if (!string.IsNullOrEmpty(sOrderBy)) { sql += $" ORDER BY {sOrderBy}"; } result = (await conn.QueryAsync(sql, param)).ToList(); } catch (Exception exception) { throw exception; } return result; } } /// /// 根據SQL語句抓取整包資料 /// /// /// /// public virtual async Task> GetAllAsync(string sqlString, object param = null) { List result; using (IDbConnection conn = GetDbConnection()) { try { var sql = sqlString; result = (await conn.QueryAsync(sql, param)).ToList(); } catch (Exception exception) { throw exception; } return result; } } /// /// 取得多筆資料的某個欄位變成列表 /// /// 流水號 /// 資料表名稱 /// 指定欄位名稱的流水號 /// 選擇陣列資料庫欄位名稱 /// public virtual async Task> GetAllWithCustomDBNameAndTableAsync(string guid, string table_name, string idName, string selCol) { List result; using (IDbConnection conn = GetDbConnection()) { try { var sql = $"SELECT {selCol} FROM {table_name} WHERE {idName} = @Guid"; result = (await conn.QueryAsync(sql, new { Guid = guid })).ToList(); } catch (Exception exception) { throw exception; } return result; } } #endregion GetAll #region GetOne /// /// 取得單一筆資料(排序) /// /// /// /// /// 參數值 /// /// public virtual async Task GetOneAsync(string tableName, string sWhere, object param = null, string sOrderBy = "") { A result; using (IDbConnection conn = GetDbConnection()) { try { var sql = $"SELECT * FROM {tableName}"; if (!string.IsNullOrEmpty(sWhere)) { sql += $" WHERE {sWhere}"; } if (!string.IsNullOrEmpty(sOrderBy)) { sql += $" ORDER BY {sOrderBy}"; } result = await conn.QueryFirstOrDefaultAsync(sql, param); } catch (Exception exception) { throw exception; } return result; } } /// /// 取得單一筆資料某一欄位(排序) /// /// /// /// 填放欄位 /// 參數值 /// /// public virtual async Task GetOneAsync(string tableName, string sWhere, string selCol, object param = null, string sOrderBy = "") { object result; using (IDbConnection conn = GetDbConnection()) { try { var sql = $"SELECT {selCol} FROM {tableName}"; if (!string.IsNullOrEmpty(sWhere)) { sql += $" WHERE {sWhere}"; } if (!string.IsNullOrEmpty(sOrderBy)) { sql += $" ORDER BY {sOrderBy}"; } result = await conn.QueryFirstOrDefaultAsync(sql, param); } catch (Exception exception) { throw exception; } return result; } } /// /// 取得單一筆資料(根據自訂SQL, 自訂參數) /// /// /// /// public virtual async Task GetOneAsync(string sqlString, object param = null) { A result; using (IDbConnection conn = GetDbConnection()) { try { var sql = sqlString; result = await conn.QueryFirstOrDefaultAsync(sql, param); } catch (Exception exception) { throw exception; } return result; } } #endregion GetOne #region DeleteOne (軟刪除) /// /// 透過guid,軟刪除單一筆資料 /// UPDATE {tableName} SET deleted = 1 WHERE {idName} = @Guid /// /// /// public virtual async Task DeleteOne(string guid, string tableName, string idName) { using (IDbConnection conn = GetDbConnection()) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { var sql = $"UPDATE {tableName} SET deleted = 1 WHERE {idName} = @Guid"; if (UseDB == "MSSQL" && !exclude_data_delivery.Contains(tableName)) { Dictionary dict = new Dictionary() { { idName, guid}, { "@deleted", 1}, }; backgroundService = new BackgroundService(conn, trans); await backgroundService.AddTask("", "", tableName, "delete", dict, null, guid); } await conn.ExecuteAsync(sql, new { Guid = guid }, trans); trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } finally { conn.Close(); } } } } /// /// 透過guid、db_name、table_name,刪除指定的資料庫之資料表的一筆資料 /// /// /// /// /// public virtual async Task DeleteOneByGuidWithCustomDBNameAndTable(string guid, string db_name, string table_name, string idName) { using (IDbConnection conn = GetDbConnection()) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { var sql = $"UPDATE {db_name}.{table_name} SET Deleted = 1 WHERE {idName} = @Guid"; if (UseDB == "MSSQL" && !exclude_data_delivery.Contains(table_name)) { Dictionary dict = new Dictionary() { { idName, guid}, { "@deleted", 1}, }; backgroundService = new BackgroundService(conn, trans); await backgroundService.AddTask("", "", $"{db_name}.{table_name}", "delete", dict, null, guid); } await conn.ExecuteAsync(sql, new { Guid = guid }, trans); trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } finally { conn.Close(); } } } } #endregion DeleteOne (軟刪除) #region PurgeOne (硬刪除) /// /// 根據Where條件進行刪除 /// /// /// /// public virtual async Task PurgeOneByGuidWithCustomDBNameAndTable(string table_name, string sWhere) { using (IDbConnection conn = GetDbConnection()) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { var sql = $"DELETE FROM {table_name} WHERE {sWhere}"; if (UseDB == "MSSQL" && !exclude_data_delivery.Contains(table_name)) { Dictionary dict = new Dictionary(); //判斷是否有and的情況 var swhere_splits_and = sWhere.Split("and"); foreach (var sWhere_and in swhere_splits_and) { var swhere_split = sWhere_and.Split('='); if (swhere_split.Length > 0) { dict.Add(swhere_split[0].Trim(), swhere_split[1].Replace("'", "").Trim()); } } backgroundService = new BackgroundService(conn, trans); await backgroundService.AddTask("", "", table_name, "purge", dict); } await conn.ExecuteAsync(sql, null, trans); trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } finally { conn.Close(); } } } } /// /// 指定單一欄位,實際刪除單一筆資料 /// /// /// /// /// public virtual async Task PurgeOneAsync(string guid, string table_name, string idName) { using (IDbConnection conn = GetDbConnection()) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { var sql = $"DELETE FROM {table_name} WHERE {idName} = @Guid"; if (UseDB == "MSSQL" && !exclude_data_delivery.Contains(table_name)) { Dictionary dict = new Dictionary() { { idName, guid}, }; backgroundService = new BackgroundService(conn, trans); await backgroundService.AddTask("", "", table_name, "purge", dict, null, guid); } await conn.ExecuteAsync(sql, new { Guid = guid }, trans); trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } finally { conn.Close(); } } } } #endregion PurgeOne (硬刪除) #region AddMuti /// /// 新增Table多筆資料 /// /// /// /// public async Task AddMutiByCustomTable(List> dict, string Table_name) { using (IDbConnection conn = GetDbConnection()) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { List properties = dict[0].Keys.ToList(); string sql = InsertGenerateString(properties, Table_name); await conn.ExecuteAsync(sql, dict, trans); if (UseDB == "MSSQL" && !exclude_data_delivery.Contains(Table_name)) { backgroundService = new BackgroundService(conn, trans); await backgroundService.AddTask("", "", Table_name, "insert_list", dict); } trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } finally { conn.Close(); } } } } #endregion AddMuti #region AddOne /// /// 新增table一筆資料 /// /// 新增資料庫名稱以及值 /// 資料表名稱 /// public async Task AddOneByCustomTable(Dictionary dict, string Table_name) { using (IDbConnection conn = GetDbConnection()) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { List properties = dict.Keys.ToList(); string sql = InsertGenerateString(properties, Table_name); await conn.ExecuteAsync(sql, dict, trans); if (UseDB == "MSSQL" && !exclude_data_delivery.Contains(Table_name)) { backgroundService = new BackgroundService(conn, trans); await backgroundService.AddTask("", "", Table_name, "insert", dict); } trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } finally { conn.Close(); } } } } #endregion AddOne #region UpdateOne /// /// 更新Table一筆資料 /// /// 更新資料庫名稱以及值 /// 資料表名稱 /// Where條件 /// public async Task UpdateOneByCustomTable(Dictionary dict, string Table_name, string sWhere) { using (IDbConnection conn = GetDbConnection()) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { List properties = dict.Keys.ToList(); string sql = UpdateGenerateString(properties, Table_name, sWhere); await conn.ExecuteAsync(sql, dict, trans); if (UseDB == "MSSQL" && !exclude_data_delivery.Contains(Table_name)) { //判斷是否有and的情況 var swhere_splits_and = sWhere.Split("and"); foreach(var sWhere_and in swhere_splits_and) { var swhere_split = sWhere_and.Split('='); if (swhere_split.Length > 0) { dict.Add(swhere_split[0].Trim(), swhere_split[1].Replace("'", "").Trim()); } } backgroundService = new BackgroundService(conn, trans); await backgroundService.AddTask("", "", Table_name, "update", dict); } trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } finally { conn.Close(); } } } } #endregion UpdateOne #region UpdateList /// /// 更新Table多筆筆資料 /// /// 更新資料庫名稱以及值 /// 資料表名稱 /// Where條件 /// public async Task UpdateListByCustomTable(List> dicts, string Table_name, string sWhere) { using (IDbConnection conn = GetDbConnection()) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { List properties = dicts.First().Keys.ToList(); string sql = UpdateGenerateString(properties, Table_name, sWhere); await conn.ExecuteAsync(sql, dicts, trans); if (UseDB == "MSSQL" && !exclude_data_delivery.Contains(Table_name)) { backgroundService = new BackgroundService(conn, trans); await backgroundService.AddTask("", "", Table_name, "update_list", dicts); } trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } finally { conn.Close(); } } } } #endregion UpdateList /// /// 取資料庫當前流水號 /// /// /// /// public async Task GetCurrentSerialNumber(string Table_name, string where = "") { string Num; using (IDbConnection conn = GetDbConnection()) { conn.Open(); try { var sql = @$"SELECT SerialNumber FROM {Table_name}"; if (!string.IsNullOrEmpty(where)) { sql += $" WHERE {where}"; } sql += " ORDER BY SerialNumber DESC"; Num = await conn.QueryFirstOrDefaultAsync(sql); } catch (Exception exception) { throw exception; } finally { conn.Close(); } } return Num; } /// /// 取資料表當前優先序 /// SELECT Priority FROM {Table_name} WHERE {where} ORDER BY Priority DESC /// /// /// /// public async Task GetCurrentPriority(string Table_name, string where = "") { int Num = 0; using (IDbConnection conn = GetDbConnection()) { conn.Open(); try { var sql = @$"SELECT Priority FROM {Table_name}"; if (!string.IsNullOrEmpty(where)) { sql += $" WHERE {where}"; } sql += " ORDER BY Priority DESC"; Num = await conn.QueryFirstOrDefaultAsync(sql); } catch (Exception exception) { throw exception; } finally { conn.Close(); } } return Num; } /// /// 透過id來搜尋此筆資料是否存在 /// /// id值 /// table名稱 /// id名稱 /// public async Task HasExistsWithGuid(string guid, string Table_name, string id_name) { using (IDbConnection conn = GetDbConnection()) { Boolean hasExists = false; conn.Open(); try { var sql = $"SELECT * FROM {Table_name} WHERE {id_name} = @Guid"; var result = await conn.QueryFirstOrDefaultAsync(sql, new { Guid = guid }); if (result != null) { hasExists = true; } } catch (Exception exception) { throw exception; } finally { conn.Close(); } return hasExists; } } /// /// 根據SQL條件搜尋此筆資料是否存在 /// /// /// public async Task HasExistsWithParam(string sql, object param = null) { using (IDbConnection conn = GetDbConnection()) { Boolean hasExists = false; conn.Open(); try { var result = await conn.QueryFirstOrDefaultAsync(sql, param); if (result != null) { hasExists = true; } } catch (Exception exception) { throw exception; } finally { conn.Close(); } return hasExists; } } /// /// 直接執行SQL語句 /// /// /// /// public async Task ExecuteSql(string sql, object param = null) { using (IDbConnection conn = GetDbConnection()) { conn.Open(); try { var result = await conn.ExecuteAsync(sql, param); } catch (Exception exception) { throw exception; } finally { conn.Close(); } } } #region AddOneReturnId /// /// 新增table一筆資料 /// /// 新增資料庫名稱以及值 /// 資料表名稱 /// public async Task AddOneByCustomTableReturnId(Dictionary dict, string Table_name, bool returnId = true) { var id = 0; using (IDbConnection conn = GetDbConnection()) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { List properties = dict.Keys.ToList(); string sql = InsertGenerateString(properties, Table_name); if (returnId) { sql += " SELECT SCOPE_IDENTITY()"; } id = await conn.QueryFirstOrDefaultAsync(sql, dict, trans); //await conn.ExecuteAsync(sql, dict, trans); trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } finally { conn.Close(); } } } return id; } #endregion AddOneReturnId } }