ibms-dome/Repository/BaseRepository/Implement/BaseRepository.cs

929 lines
32 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<string> exclude_data_delivery = new List<string>()
{
"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<string> 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<string> 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
/// <summary>
/// 取得所有資料(根據條件以及排序)
/// </summary>
/// <typeparam name="A"></typeparam>
/// <param name="tableName"></param>
/// <param name="sWhere"></param>
/// <param name="param">Ex: new { status = 1}</param>
/// <returns></returns>
public virtual async Task<List<A>> GetAllAsync<A>(string tableName, string sWhere, object param = null, string sOrderBy = "")
{
List<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.QueryAsync<A>(sql, param)).ToList();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
/// <summary>
/// 根據SQL語句抓取整包資料
/// </summary>
/// <typeparam name="A"></typeparam>
/// <param name="sqlString"></param>
/// <returns></returns>
public virtual async Task<List<A>> GetAllAsync<A>(string sqlString, object param = null)
{
List<A> result;
using (IDbConnection conn = GetDbConnection())
{
try
{
var sql = sqlString;
result = (await conn.QueryAsync<A>(sql, param)).ToList();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
/// <summary>
/// 取得多筆資料的某個欄位變成列表
/// </summary>
/// <param name="guid">流水號</param>
/// <param name="table_name">資料表名稱</param>
/// <param name="idName">指定欄位名稱的流水號</param>
/// <param name="selCol">選擇陣列資料庫欄位名稱</param>
/// <returns></returns>
public virtual async Task<List<object>> GetAllWithCustomDBNameAndTableAsync(string guid, string table_name, string idName, string selCol)
{
List<object> result;
using (IDbConnection conn = GetDbConnection())
{
try
{
var sql = $"SELECT {selCol} FROM {table_name} WHERE {idName} = @Guid";
result = (await conn.QueryAsync<object>(sql, new { Guid = guid })).ToList();
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
#endregion GetAll
#region GetOne
/// <summary>
/// 取得單一筆資料(排序)
/// </summary>
/// <typeparam name="A"></typeparam>
/// <param name="tableName"></param>
/// <param name="sWhere"></param>
/// <param name="param">參數值</param>
/// <param name="sOrderBy"></param>
/// <returns></returns>
public virtual async Task<A> GetOneAsync<A>(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<A>(sql, param);
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
/// <summary>
/// 取得單一筆資料某一欄位(排序)
/// </summary>
/// <param name="tableName"></param>
/// <param name="sWhere"></param>
/// <param name="selCol">填放欄位</param>
/// <param name="param">參數值</param>
/// <param name="sOrderBy"></param>
/// <returns></returns>
public virtual async Task<object> 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<object>(sql, param);
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
/// <summary>
/// 取得單一筆資料(根據自訂SQL, 自訂參數)
/// </summary>
/// <param name="sqlString"></param>
/// <param name="param"></param>
/// <returns></returns>
public virtual async Task<A> GetOneAsync<A>(string sqlString, object param = null)
{
A result;
using (IDbConnection conn = GetDbConnection())
{
try
{
var sql = sqlString;
result = await conn.QueryFirstOrDefaultAsync<A>(sql, param);
}
catch (Exception exception)
{
throw exception;
}
return result;
}
}
#endregion GetOne
#region DeleteOne ()
/// <summary>
/// 透過guid軟刪除單一筆資料
/// UPDATE {tableName} SET deleted = 1 WHERE {idName} = @Guid
/// </summary>
/// <param name="guid"></param>
/// <returns></returns>
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<string, object> dict = new Dictionary<string, object>()
{
{ 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();
}
}
}
}
/// <summary>
/// 透過guid、db_name、table_name刪除指定的資料庫之資料表的一筆資料
/// </summary>
/// <param name="guid"></param>
/// <param name="db_name"></param>
/// <param name="table_name"></param>
/// <returns></returns>
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<string, object> dict = new Dictionary<string, object>()
{
{ 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 ()
/// <summary>
/// 根據Where條件進行刪除
/// </summary>
/// <param name="table_name"></param>
/// <param name="sWhere"></param>
/// <returns></returns>
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<string, object> dict = new Dictionary<string, object>();
//判斷是否有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();
}
}
}
}
/// <summary>
/// 指定單一欄位,實際刪除單一筆資料
/// </summary>
/// <param name="guid"></param>
/// <param name="table_name"></param>
/// <param name="idName"></param>
/// <returns></returns>
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<string, object> dict = new Dictionary<string, object>()
{
{ 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
/// <summary>
/// 新增Table多筆資料
/// </summary>
/// <param name="dict"></param>
/// <param name="Table_name"></param>
/// <returns></returns>
public async Task AddMutiByCustomTable(List<Dictionary<string, object>> dict, string Table_name)
{
using (IDbConnection conn = GetDbConnection())
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
try
{
List<string> 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
/// <summary>
/// 新增table一筆資料
/// </summary>
/// <param name="dict">新增資料庫名稱以及值</param>
/// <param name="Table_name">資料表名稱</param>
/// <returns></returns>
public async Task AddOneByCustomTable(Dictionary<string, object> dict, string Table_name)
{
using (IDbConnection conn = GetDbConnection())
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
try
{
List<string> 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
/// <summary>
/// 更新Table一筆資料
/// </summary>
/// <param name="dict">更新資料庫名稱以及值</param>
/// <param name="Table_name">資料表名稱</param>
/// <param name="sWhere">Where條件</param>
/// <returns></returns>
public async Task UpdateOneByCustomTable(Dictionary<string, object> dict, string Table_name, string sWhere)
{
using (IDbConnection conn = GetDbConnection())
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
try
{
List<string> 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
/// <summary>
/// 更新Table多筆筆資料
/// </summary>
/// <param name="dict">更新資料庫名稱以及值</param>
/// <param name="Table_name">資料表名稱</param>
/// <param name="sWhere">Where條件</param>
/// <returns></returns>
public async Task UpdateListByCustomTable(List<Dictionary<string, object>> dicts, string Table_name, string sWhere)
{
using (IDbConnection conn = GetDbConnection())
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
try
{
List<string> 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
/// <summary>
/// 取資料庫當前流水號
/// </summary>
/// <param name="Table_name"></param>
/// <param name="where"></param>
/// <returns></returns>
public async Task<string> 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<string>(sql);
}
catch (Exception exception)
{
throw exception;
}
finally
{
conn.Close();
}
}
return Num;
}
/// <summary>
/// 取資料表當前優先序
/// <para>SELECT Priority FROM {Table_name} WHERE {where} ORDER BY Priority DESC</para>
/// </summary>
/// <param name="Table_name"></param>
/// <param name="where"></param>
/// <returns></returns>
public async Task<int> 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<int>(sql);
}
catch (Exception exception)
{
throw exception;
}
finally
{
conn.Close();
}
}
return Num;
}
/// <summary>
/// 透過id來搜尋此筆資料是否存在
/// </summary>
/// <param name="id">id值</param>
/// <param name="Table_name">table名稱</param>
/// <param name="id_name">id名稱</param>
/// <returns></returns>
public async Task<Boolean> 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<string>(sql, new { Guid = guid });
if (result != null)
{
hasExists = true;
}
}
catch (Exception exception)
{
throw exception;
}
finally
{
conn.Close();
}
return hasExists;
}
}
/// <summary>
/// 根據SQL條件搜尋此筆資料是否存在
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public async Task<Boolean> HasExistsWithParam(string sql, object param = null)
{
using (IDbConnection conn = GetDbConnection())
{
Boolean hasExists = false;
conn.Open();
try
{
var result = await conn.QueryFirstOrDefaultAsync<object>(sql, param);
if (result != null)
{
hasExists = true;
}
}
catch (Exception exception)
{
throw exception;
}
finally
{
conn.Close();
}
return hasExists;
}
}
/// <summary>
/// 直接執行SQL語句
/// </summary>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <returns></returns>
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
/// <summary>
/// 新增table一筆資料
/// </summary>
/// <param name="dict">新增資料庫名稱以及值</param>
/// <param name="Table_name">資料表名稱</param>
/// <returns></returns>
public async Task<int> AddOneByCustomTableReturnId(Dictionary<string, object> dict, string Table_name, bool returnId = true)
{
var id = 0;
using (IDbConnection conn = GetDbConnection())
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
try
{
List<string> properties = dict.Keys.ToList();
string sql = InsertGenerateString(properties, Table_name);
if (returnId)
{
sql += " SELECT LAST_INSERT_ID()";
}
id = await conn.QueryFirstOrDefaultAsync<int>(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
#region TruncateTable ()
/// <summary>
/// 清空資料表資料
/// TRUNCATE TABLE {tableName}
/// </summary>
/// <param name="table_name"></param>
/// <returns></returns>
public virtual async Task TruncateTable(string table_name)
{
using (IDbConnection conn = GetDbConnection())
{
conn.Open();
using (var trans = conn.BeginTransaction())
{
try
{
var sql = $"TRUNCATE TABLE {table_name}";
await conn.ExecuteAsync(sql, null, trans);
trans.Commit();
}
catch (Exception exception)
{
trans.Rollback();
throw exception;
}
finally
{
conn.Close();
}
}
}
}
#endregion TruncateTable
}
}