SqlSugarHelper.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. using Microsoft.Data.SqlClient;
  2. using Newtonsoft.Json.Linq;
  3. using SqlSugar;
  4. using System.Data;
  5. namespace ServiceCenter.SqlSugars
  6. {
  7. /// <summary>
  8. /// ORM
  9. /// </summary>
  10. public class SqlSugarHelper
  11. {
  12. /// <summary>
  13. /// 数据库连接
  14. /// </summary>
  15. private static SqlSugarScope? _Db { get; set; } = null;
  16. /// <summary>
  17. /// 默认数据库连接Key
  18. /// </summary>
  19. private static string _Default { get; set; } = "";
  20. /// <summary>
  21. /// PLC据库连接Key
  22. /// </summary>
  23. private static string _PLCEX { get; set; } = "";
  24. /// <summary>
  25. /// PLC据库连接Key
  26. /// </summary>
  27. public static string _PLC { get; set; } = "";
  28. /// <summary>
  29. /// Dlog数据库连接Key
  30. /// </summary>
  31. private static string _Dlog { get; set; } = "";
  32. /// <summary>
  33. /// 设置数据库连接Key
  34. /// </summary>
  35. /// <param name="configId">默认多租户ID</param>
  36. public static void SetDefault(string configId)
  37. {
  38. _Default = configId;
  39. }
  40. /// <summary>
  41. /// 设置 Dlog数据库连接Key
  42. /// </summary>
  43. /// <param name="configId">多租户Dlog ID</param>
  44. public static void SetDlog(string configId)
  45. {
  46. _Dlog = configId;
  47. }
  48. /// <summary>
  49. /// 设置 plc数据库连接Key
  50. /// </summary>
  51. /// <param name="configId">多租户Dlog ID</param>
  52. public static void SetPLC(string configId)
  53. {
  54. _PLC = configId;
  55. }
  56. /// <summary>
  57. /// 设置 plc数据库连接Key
  58. /// </summary>
  59. /// <param name="configId">多租户Dlog ID</param>
  60. public static void SetPLCEX(string configId)
  61. {
  62. _PLCEX = configId;
  63. }
  64. /// <summary>
  65. /// 默认数据库连接Key
  66. /// </summary>
  67. public SqlSugarScopeProvider Default
  68. {
  69. get
  70. {
  71. if (_Default == "") throw new Exception("请调用[SqlSugarHelper.SetDefault]方法设置默认数据库连接");
  72. if (_Db == null) throw new Exception("请调用[SqlSugarHelper.SetDb]方法设置设置数据库连接");
  73. return _Db.GetConnectionScope(_Default);
  74. }
  75. }
  76. /// <summary>
  77. /// Dlog数据库连接Key
  78. /// </summary>
  79. public SqlSugarScopeProvider Dlog
  80. {
  81. get
  82. {
  83. if (_Dlog == "") throw new Exception("请调用[SqlSugarHelper.SetDlog]方法设置默认数据库连接");
  84. if (_Db == null) throw new Exception("请调用[SqlSugarHelper.SetDb]方法设置设置数据库连接");
  85. return _Db.GetConnectionScope(_Dlog);
  86. }
  87. }
  88. /// <summary>
  89. /// plc数据库连接Key
  90. /// </summary>
  91. public SqlSugarScopeProvider PLC
  92. {
  93. get
  94. {
  95. if (_PLC == "") throw new Exception("请调用[SqlSugarHelper.SetPLC]方法设置默认数据库连接");
  96. if (_Db == null) throw new Exception("请调用[SqlSugarHelper.SetDb]方法设置设置数据库连接");
  97. return _Db.GetConnectionScope(_PLC);
  98. }
  99. }
  100. /// <summary>
  101. /// plc数据库连接Key
  102. /// </summary>
  103. public SqlSugarScopeProvider PLCEX
  104. {
  105. get
  106. {
  107. if (_PLCEX == "") throw new Exception("请调用[SqlSugarHelper.SetPLC]方法设置默认数据库连接");
  108. if (_Db == null) throw new Exception("请调用[SqlSugarHelper.SetDb]方法设置设置数据库连接");
  109. return _Db.GetConnectionScope(_PLCEX);
  110. }
  111. }
  112. /// <summary>
  113. /// 设置数据库连接
  114. /// </summary>
  115. /// <param name="sqlSugarScope"></param>
  116. public static void SetDb(SqlSugarScope sqlSugarScope)
  117. {
  118. _Db = sqlSugarScope;
  119. }
  120. /// <summary>
  121. /// 数据库连接
  122. /// 注意需要
  123. /// </summary>
  124. public SqlSugarScope Connect
  125. {
  126. get
  127. {
  128. return _Db ?? throw new Exception("请调用[SqlSugarHelper.SetDb]方法设置设置数据库连接");
  129. }
  130. }
  131. /// <summary>
  132. /// 执行事务
  133. /// </summary>
  134. /// <param name="act"></param>
  135. /// <exception cref="Exception"></exception>
  136. public static void Do(Action<SqlSugarHelper> act)
  137. {
  138. if (_Db == null) throw new Exception("请调用[SqlSugarHelper.SetDb]方法设置设置数据库连接");
  139. // 创建独立的SqlSugarHelper实例,避免共享事务状态
  140. var db = new SqlSugarHelper();
  141. try
  142. {
  143. // 使用 SqlSugar 的 Ado.UseTran 方法进行事务管理(推荐方式)
  144. var result = db.Connect.Ado.UseTran(() =>
  145. {
  146. act(db);
  147. });
  148. if (!result.IsSuccess)
  149. {
  150. if (result.ErrorMessage.Contains("SqlTransaction"))
  151. {
  152. throw new Exception($"事务处理失败 - {result.ErrorMessage}。这通常是由于事务状态冲突导致的,请检查并发访问情况。");
  153. }
  154. throw new Exception($"事务执行失败: {result.ErrorMessage}");
  155. }
  156. }
  157. catch (Exception ex)
  158. {
  159. // 如果 UseTran 方法不可用,回退到手动事务管理
  160. if (ex.Message.Contains("UseTran") || ex is System.MissingMethodException)
  161. {
  162. DoWithManualTransaction(act, db);
  163. }
  164. else
  165. {
  166. throw;
  167. }
  168. }
  169. }
  170. /// <summary>
  171. /// 手动事务管理的回退方法
  172. /// </summary>
  173. private static void DoWithManualTransaction(Action<SqlSugarHelper> act, SqlSugarHelper db)
  174. {
  175. var transactionStarted = false;
  176. try
  177. {
  178. // 检查是否已经在事务中
  179. if (db.Connect.Ado.Transaction == null)
  180. {
  181. db.Connect.BeginTran();
  182. transactionStarted = true;
  183. }
  184. act(db);
  185. if (transactionStarted)
  186. {
  187. db.Connect.CommitTran();
  188. }
  189. }
  190. catch (Exception ex)
  191. {
  192. if (transactionStarted)
  193. {
  194. try
  195. {
  196. db.Connect.RollbackTran();
  197. }
  198. catch (Exception rollbackEx)
  199. {
  200. throw new Exception($"原始错误: {ex.Message}; 回滚失败: {rollbackEx.Message}");
  201. }
  202. }
  203. if (ex.Message.Contains("SqlTransaction"))
  204. {
  205. throw new Exception($"事务处理失败 - {ex.Message}。这通常是由于事务已被提交或回滚后再次使用导致的。建议检查事务的使用方式和并发访问。");
  206. }
  207. throw new Exception($"事务执行失败: {ex.Message}");
  208. }
  209. }
  210. /// <summary>
  211. /// 直接返回查询结果
  212. /// </summary>
  213. /// <typeparam name="T"></typeparam>
  214. /// <param name="act"></param>
  215. /// <returns></returns>
  216. /// <exception cref="Exception"></exception>
  217. public static T Do<T>(Func<SqlSugarHelper, T> act)
  218. {
  219. if (_Db == null) throw new Exception("请调用[SqlSugarHelper.SetDb]方法设置设置数据库连接");
  220. // 创建独立的SqlSugarHelper实例,避免共享事务状态
  221. var db = new SqlSugarHelper();
  222. try
  223. {
  224. // 使用 SqlSugar 的 Ado.UseTran 方法进行事务管理(推荐方式)
  225. var result = db.Connect.Ado.UseTran(() =>
  226. {
  227. db.Connect.Ado.CommandTimeOut = 10;
  228. return act(db);
  229. });
  230. if (!result.IsSuccess)
  231. {
  232. if (result.ErrorMessage.Contains("SqlTransaction"))
  233. {
  234. throw new Exception($"事务处理失败 - {result.ErrorMessage}。这通常是由于事务状态冲突导致的,请检查并发访问情况。");
  235. }
  236. throw new Exception($"事务执行失败: {result.ErrorMessage}");
  237. }
  238. return result.Data;
  239. }
  240. catch (Exception ex)
  241. {
  242. // 如果 UseTran 方法不可用,回退到手动事务管理
  243. if (ex.Message.Contains("UseTran") || ex is System.MissingMethodException)
  244. {
  245. return DoWithManualTransaction(act, db);
  246. }
  247. else
  248. {
  249. throw;
  250. }
  251. }
  252. }
  253. /// <summary>
  254. /// 手动事务管理的回退方法(带返回值)
  255. /// </summary>
  256. private static T DoWithManualTransaction<T>(Func<SqlSugarHelper, T> act, SqlSugarHelper db)
  257. {
  258. var transactionStarted = false;
  259. try
  260. {
  261. // 检查是否已经在事务中
  262. if (db.Connect.Ado.Transaction == null)
  263. {
  264. db.Connect.BeginTran();
  265. transactionStarted = true;
  266. }
  267. db.Connect.Ado.CommandTimeOut = 10;
  268. var result = act(db);
  269. if (transactionStarted)
  270. {
  271. db.Connect.CommitTran();
  272. }
  273. return result;
  274. }
  275. catch (Exception ex)
  276. {
  277. if (transactionStarted)
  278. {
  279. try
  280. {
  281. db.Connect.RollbackTran();
  282. }
  283. catch (Exception rollbackEx)
  284. {
  285. throw new Exception($"原始错误: {ex.Message}; 回滚失败: {rollbackEx.Message}");
  286. }
  287. }
  288. if (ex.Message.Contains("SqlTransaction"))
  289. {
  290. throw new Exception($"事务处理失败 - {ex.Message}。这通常是由于事务已被提交或回滚后再次使用导致的。建议检查事务的使用方式和并发访问。");
  291. }
  292. throw new Exception($"事务执行失败: {ex.Message}");
  293. }
  294. }
  295. }
  296. }