SQLiteHelper.cs 16 KB

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