SQLiteHelper.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Data.SQLite;
  5. using System.IO;
  6. using System.Threading.Tasks;
  7. namespace MeterVision.db
  8. {
  9. public abstract class SQLiteHelper
  10. {
  11. private static string DBFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "MeterVision.db");
  12. //private static string connectionString = $"data source={DBFileName}";
  13. private static string connectionString = $"Data Source={DBFileName};Version=3;";
  14. /// <summary>
  15. /// 获取连接字符串
  16. /// </summary>
  17. public static string GetConnStr()
  18. {
  19. return connectionString;
  20. }
  21. /// <summary>
  22. /// 创建本地库连接
  23. /// </summary>
  24. /// <returns>返回本地库连接</returns>
  25. public static SQLiteConnection CreateConn()
  26. {
  27. return new SQLiteConnection(connectionString);
  28. }
  29. // 获取 SQLite 数据库连接
  30. public static SQLiteConnection GetConnection()
  31. {
  32. return new SQLiteConnection(connectionString);
  33. }
  34. // 执行 SQL 命令(不返回结果集,仅返回受影响的行数)
  35. public static int ExecuteNonQuery(string sql, SQLiteParameter[] parameters)
  36. {
  37. using (SQLiteConnection conn = GetConnection())
  38. {
  39. conn.Open();
  40. using (SQLiteCommand cmd = new SQLiteCommand(sql, conn))
  41. {
  42. // 添加参数
  43. if (parameters != null)
  44. {
  45. cmd.Parameters.AddRange(parameters);
  46. }
  47. // 执行 SQL 语句并返回受影响的行数
  48. return cmd.ExecuteNonQuery();
  49. }
  50. }
  51. }
  52. // 支持事务的 ExecuteNonQuery
  53. public static int ExecuteNonQuery(string sql, SQLiteParameter[] parameters, SQLiteTransaction transaction)
  54. {
  55. using (SQLiteCommand cmd = new SQLiteCommand(sql, transaction.Connection, transaction))
  56. {
  57. if (parameters != null)
  58. {
  59. cmd.Parameters.AddRange(parameters);
  60. }
  61. return cmd.ExecuteNonQuery();
  62. }
  63. }
  64. /// <summary>
  65. /// 执行查询语句,返回一个值
  66. /// </summary>
  67. /// <param name="SQLString">SQL语句</param>
  68. /// <returns>返回的值</returns>
  69. public static int ExecuteSel(string SQLString)
  70. {
  71. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  72. using (SQLiteCommand cmd = new SQLiteCommand(SQLString, connection))
  73. {
  74. try
  75. {
  76. connection.Open();
  77. return Convert.ToInt32(cmd.ExecuteScalar());
  78. }
  79. catch (SQLiteException e)
  80. {
  81. throw new Exception("Error executing SELECT query.", e);
  82. }
  83. }
  84. }
  85. /// <summary>
  86. /// 执行SQL语句,返回影响的记录数
  87. /// </summary>
  88. /// <param name="SQLString">SQL语句</param>
  89. /// <returns>影响的记录数</returns>
  90. public static int ExecuteSql(string SQLString)
  91. {
  92. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  93. using (SQLiteCommand cmd = new SQLiteCommand(SQLString, connection))
  94. {
  95. try
  96. {
  97. connection.Open();
  98. return cmd.ExecuteNonQuery();
  99. }
  100. catch (SQLiteException e)
  101. {
  102. throw new Exception("Error executing SQL.", e);
  103. }
  104. }
  105. }
  106. /// <summary>
  107. /// 执行一组SQL语句
  108. /// </summary>
  109. /// <param name="SQLList">SQL语句集合</param>
  110. /// <returns>成功返回True,失败返回False</returns>
  111. public static bool ExecuteSql(List<string> SQLList)
  112. {
  113. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  114. {
  115. connection.Open();
  116. using (SQLiteTransaction transaction = connection.BeginTransaction())
  117. {
  118. try
  119. {
  120. foreach (var SQL in SQLList)
  121. {
  122. using (SQLiteCommand cmd = new SQLiteCommand(SQL, connection))
  123. {
  124. cmd.ExecuteNonQuery();
  125. }
  126. }
  127. transaction.Commit();
  128. return true;
  129. }
  130. catch (SQLiteException e)
  131. {
  132. transaction.Rollback();
  133. throw new Exception("Transaction failed, rolled back.", e);
  134. }
  135. }
  136. }
  137. }
  138. /// <summary>
  139. /// 执行SQL语句,带参数
  140. /// </summary>
  141. /// <param name="SQLString">SQL语句</param>
  142. /// <param name="cmdParms">SQL参数</param>
  143. /// <returns>影响的记录数</returns>
  144. public static int ExecuteSql(string SQLString, SQLiteParameter[] cmdParms)
  145. {
  146. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  147. using (SQLiteCommand cmd = new SQLiteCommand())
  148. {
  149. try
  150. {
  151. PrepareCommand(cmd, connection, null, SQLString, cmdParms);
  152. return cmd.ExecuteNonQuery();
  153. }
  154. catch (SQLiteException e)
  155. {
  156. throw new Exception("Error executing parameterized SQL.", e);
  157. }
  158. }
  159. }
  160. private static void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, SQLiteTransaction trans, string cmdText, SQLiteParameter[] cmdParms)
  161. {
  162. if (conn.State != ConnectionState.Open)
  163. conn.Open();
  164. cmd.Connection = conn;
  165. cmd.CommandText = cmdText;
  166. if (trans != null)
  167. cmd.Transaction = trans;
  168. cmd.CommandType = CommandType.Text;
  169. if (cmdParms != null)
  170. {
  171. foreach (SQLiteParameter parameter in cmdParms)
  172. {
  173. if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) && (parameter.Value == null))
  174. {
  175. parameter.Value = DBNull.Value;
  176. }
  177. cmd.Parameters.Add(parameter);
  178. }
  179. }
  180. }
  181. /// <summary>
  182. /// 删除指定表的所有数据
  183. /// </summary>
  184. /// <param name="TableName">指定的表名</param>
  185. /// <returns>影响的记录数</returns>
  186. public static int DelTableData(string TableName)
  187. {
  188. string SQLString = $"DELETE FROM '{TableName}'";
  189. return ExecuteSql(SQLString);
  190. }
  191. /// <summary>
  192. /// 执行查询语句,返回单个值
  193. /// </summary>
  194. /// <param name="SQLString">查询语句</param>
  195. /// <returns>查询结果(object)</returns>
  196. public static object GetSingle(string SQLString)
  197. {
  198. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  199. using (SQLiteCommand cmd = new SQLiteCommand(SQLString, connection))
  200. {
  201. try
  202. {
  203. connection.Open();
  204. var result = cmd.ExecuteScalar();
  205. return result == DBNull.Value ? null : result;
  206. }
  207. catch (SQLiteException e)
  208. {
  209. throw new Exception("Error executing scalar query.", e);
  210. }
  211. }
  212. }
  213. public static object GetSingle(string sql, params SQLiteParameter[] parameters)
  214. {
  215. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  216. {
  217. connection.Open();
  218. using (SQLiteCommand command = new SQLiteCommand(sql, connection))
  219. {
  220. if (parameters != null)
  221. {
  222. command.Parameters.AddRange(parameters);
  223. }
  224. object result = command.ExecuteScalar();
  225. return result == DBNull.Value ? null : result;
  226. }
  227. }
  228. }
  229. /// <summary>
  230. /// 执行查询语句,返回DataTable
  231. /// </summary>
  232. /// <param name="SQLString">查询语句</param>
  233. /// <returns>查询结果的DataTable</returns>
  234. public static DataTable QueryTable(string SQLString)
  235. {
  236. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  237. {
  238. DataTable dt = new DataTable();
  239. try
  240. {
  241. connection.Open();
  242. using (SQLiteDataAdapter command = new SQLiteDataAdapter(SQLString, connection))
  243. {
  244. command.Fill(dt);
  245. }
  246. }
  247. catch (SQLiteException ex)
  248. {
  249. throw new Exception("Error executing query.", ex);
  250. }
  251. return dt;
  252. }
  253. }
  254. /// <summary>
  255. /// 执行查询语句,返回DataSet
  256. /// </summary>
  257. /// <param name="SQLString">查询语句</param>
  258. /// <returns>查询结果的DataSet</returns>
  259. public static DataSet Query(string SQLString)
  260. {
  261. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  262. {
  263. DataSet ds = new DataSet();
  264. try
  265. {
  266. connection.Open();
  267. using (SQLiteDataAdapter command = new SQLiteDataAdapter(SQLString, connection))
  268. {
  269. command.Fill(ds);
  270. }
  271. }
  272. catch (SQLiteException ex)
  273. {
  274. throw new Exception("Error executing query.", ex);
  275. }
  276. return ds;
  277. }
  278. }
  279. /// <summary>
  280. /// 执行查询语句,返回空表格式
  281. /// </summary>
  282. /// <param name="sTableName">表名</param>
  283. /// <returns>空表的DataTable</returns>
  284. public static DataTable QueryNullTable(string sTableName)
  285. {
  286. string SQLString = $"SELECT * FROM {sTableName} LIMIT 0";
  287. return QueryTable(SQLString);
  288. }
  289. /// <summary>
  290. /// 执行查询语句,返回SqlDataReader
  291. /// </summary>
  292. /// <param name="strSQL">查询语句</param>
  293. /// <returns>SqlDataReader</returns>
  294. public static SQLiteDataReader ExecuteReader(string strSQL)
  295. {
  296. SQLiteConnection connection = new SQLiteConnection(connectionString);
  297. SQLiteCommand cmd = new SQLiteCommand(strSQL, connection);
  298. try
  299. {
  300. connection.Open();
  301. return cmd.ExecuteReader(CommandBehavior.CloseConnection);
  302. }
  303. catch (SQLiteException e)
  304. {
  305. throw new Exception("Error executing reader.", e);
  306. }
  307. }
  308. //public static SQLiteDataReader ExecuteReader(string sql, params SQLiteParameter[] parameters)
  309. //{
  310. // SQLiteConnection connection = new SQLiteConnection(connectionString);
  311. // SQLiteCommand command = new SQLiteCommand(sql, connection);
  312. // if (parameters != null)
  313. // {
  314. // command.Parameters.AddRange(parameters);
  315. // }
  316. // return command.ExecuteReader();
  317. //}
  318. public static SQLiteDataReader ExecuteReader(string sql, params SQLiteParameter[] parameters)
  319. {
  320. SQLiteConnection connection = new SQLiteConnection(connectionString);
  321. try
  322. {
  323. // 打开连接
  324. connection.Open();
  325. SQLiteCommand command = new SQLiteCommand(sql, connection);
  326. if (parameters != null)
  327. {
  328. command.Parameters.AddRange(parameters);
  329. }
  330. // CommandBehavior.CloseConnection 确保当 reader 被关闭时,连接也会自动关闭
  331. return command.ExecuteReader(CommandBehavior.CloseConnection);
  332. }
  333. catch
  334. {
  335. // 如果发生异常,确保关闭连接
  336. if (connection.State == System.Data.ConnectionState.Open)
  337. {
  338. connection.Close();
  339. }
  340. // 重新抛出异常,便于上层捕获
  341. throw;
  342. }
  343. }
  344. public static async Task<SQLiteDataReader> ExecuteReaderAsync(string sql, params SQLiteParameter[] parameters)
  345. {
  346. // 创建一个 TaskCompletionSource,用于包装同步的 ExecuteReader 方法
  347. return await Task.Run(() =>
  348. {
  349. SQLiteConnection connection = new SQLiteConnection(connectionString);
  350. try
  351. {
  352. // 打开连接
  353. connection.Open();
  354. SQLiteCommand command = new SQLiteCommand(sql, connection);
  355. if (parameters != null)
  356. {
  357. command.Parameters.AddRange(parameters);
  358. }
  359. // CommandBehavior.CloseConnection 确保当 reader 被关闭时,连接也会自动关闭
  360. return command.ExecuteReader(CommandBehavior.CloseConnection);
  361. }
  362. catch
  363. {
  364. // 确保发生异常时关闭连接
  365. if (connection.State == System.Data.ConnectionState.Open)
  366. {
  367. connection.Close();
  368. }
  369. // 重新抛出异常供上层处理
  370. throw;
  371. }
  372. });
  373. }
  374. /// <summary>
  375. /// 执行SQL语句清理SQLite数据库的多余空间
  376. /// </summary>
  377. public static void ClearSQLite()
  378. {
  379. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  380. using (SQLiteCommand cmd = new SQLiteCommand("VACUUM", connection))
  381. {
  382. try
  383. {
  384. connection.Open();
  385. cmd.ExecuteNonQuery();
  386. }
  387. catch (SQLiteException e)
  388. {
  389. throw new Exception("Error cleaning SQLite database.", e);
  390. }
  391. }
  392. }
  393. // 查询SQLite数据库中的所有表名
  394. public static List<string> GetAllTables()
  395. {
  396. List<string> tableNames = new List<string>();
  397. // 创建数据库连接并打开
  398. using (SQLiteConnection connection = new SQLiteConnection(connectionString))
  399. {
  400. connection.Open();
  401. // SQL查询所有表
  402. string query = "SELECT name FROM sqlite_master WHERE type='table';";
  403. using (SQLiteCommand command = new SQLiteCommand(query, connection))
  404. {
  405. using (SQLiteDataReader reader = command.ExecuteReader())
  406. {
  407. while (reader.Read())
  408. {
  409. // 将表名添加到列表中
  410. tableNames.Add(reader["name"].ToString());
  411. }
  412. }
  413. }
  414. }
  415. return tableNames;
  416. }
  417. //////////////////////////////////////////////////////
  418. }
  419. }