You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

550 lines
19 KiB

  1. using Apewer;
  2. using Apewer.Internals;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Data;
  6. namespace Apewer.Source
  7. {
  8. /// <summary>查询数据表。</summary>
  9. public class Query : IQuery, IDisposable
  10. {
  11. private bool _disposed = false;
  12. private bool _success = false;
  13. private string _error = "";
  14. private string _message = "";
  15. private Exception _exception = null;
  16. private List<DataTable> _tables = new List<DataTable>();
  17. #region Property
  18. /// <summary>语句执行成功。</summary>
  19. public bool Success
  20. {
  21. get
  22. {
  23. if (_disposed) return false;
  24. return _success;
  25. }
  26. set
  27. {
  28. if (_disposed) return;
  29. _success = value;
  30. }
  31. }
  32. /// <summary>错误信息。</summary>
  33. public string Error
  34. {
  35. get
  36. {
  37. if (_disposed) return "";
  38. if (!string.IsNullOrEmpty(_error)) return _error;
  39. if (_exception == null) return "";
  40. var error = "";
  41. try { error = _exception.Message; } finally { }
  42. return error;
  43. }
  44. set
  45. {
  46. if (_disposed) return;
  47. _error = value ?? "";
  48. }
  49. }
  50. /// <summary>消息。</summary>
  51. public string Message
  52. {
  53. get
  54. {
  55. if (_disposed) return "";
  56. return _message ?? "";
  57. }
  58. set
  59. {
  60. if (_disposed) return;
  61. _message = value ?? "";
  62. }
  63. }
  64. /// <summary>语句执行失败时的 Exception 对象。</summary>
  65. public Exception Exception
  66. {
  67. get { if (_disposed) return null; return _exception; }
  68. set { if (_disposed) return; _exception = value; }
  69. }
  70. /// <summary>所有结果表。</summary>
  71. public List<DataTable> Tables
  72. {
  73. get { if (_disposed) return new List<DataTable>(); return _tables; }
  74. }
  75. /// <summary>获取默认结果表。如果设置默认结果表,会丢失设置前的所有结果表。</summary>
  76. public DataTable Table
  77. {
  78. get
  79. {
  80. if (_disposed) return null;
  81. if (_tables.Count < 1) return null;
  82. return _tables[0];
  83. }
  84. set
  85. {
  86. if (_disposed) return;
  87. Clear();
  88. if (_disposed) return;
  89. _tables.Add(value);
  90. }
  91. }
  92. /// <summary>所有表中不含内容行。</summary>
  93. public bool Empty
  94. {
  95. get
  96. {
  97. if (_disposed) return true;
  98. if (_tables.Count < 1) return true;
  99. foreach (var table in _tables)
  100. {
  101. if (table == null) continue;
  102. try
  103. {
  104. if (table.Rows.Count > 0) return false;
  105. }
  106. finally { }
  107. }
  108. return true;
  109. }
  110. }
  111. /// <summary>默认表中的数据总行数。</summary>
  112. public int Rows
  113. {
  114. get
  115. {
  116. if (_disposed) return 0;
  117. if (Table != null) return Table.Rows.Count;
  118. else return 0;
  119. }
  120. }
  121. /// <summary>默认表中的数据总列数。</summary>
  122. public int Columns
  123. {
  124. get
  125. {
  126. if (_disposed) return 0;
  127. if (Table != null) return Table.Columns.Count;
  128. else return 0;
  129. }
  130. }
  131. #endregion
  132. #region Text
  133. private string Text(object value)
  134. {
  135. var result = Constant.EmptyString;
  136. if (value != null)
  137. {
  138. if (!value.Equals(DBNull.Value))
  139. {
  140. try
  141. {
  142. result = value.ToString();
  143. }
  144. finally { }
  145. }
  146. }
  147. return result;
  148. }
  149. /// <summary>获取默认表中第 0 行、第 0 列的单元格内容。</summary>
  150. public string Text()
  151. {
  152. if (_disposed) return Constant.EmptyString;
  153. var value = Value();
  154. return Text(value);
  155. }
  156. /// <summary>获取默认表中指定行中第 0 列的内容。</summary>
  157. /// <param name="rowIndex">行索引,从 0 开始。</param>
  158. public string Text(int rowIndex)
  159. {
  160. if (_disposed) return Constant.EmptyString;
  161. var value = Value(rowIndex);
  162. return Text(value);
  163. }
  164. /// <summary>获取默认表中第 0 行指定列的内容。</summary>
  165. /// <param name="columnName">列名称。</param>
  166. public string Text(string columnName)
  167. {
  168. if (_disposed) return Constant.EmptyString;
  169. var value = Value(columnName);
  170. return Text(value);
  171. }
  172. /// <summary>获取默认表中指定单元格的内容。</summary>
  173. /// <param name="rowIndex">行索引,从 0 开始。</param>
  174. /// <param name="columnIndex">列索引,从 0 开始。</param>
  175. public string Text(int rowIndex, int columnIndex)
  176. {
  177. if (_disposed) return Constant.EmptyString;
  178. var value = Value(rowIndex, columnIndex);
  179. return Text(value);
  180. }
  181. /// <summary>获取默认表中指定单元的内容。</summary>
  182. /// <param name="rowIndex">行索引,从 0 开始。</param>
  183. /// <param name="columnName">列名称。</param>
  184. public string Text(int rowIndex, string columnName)
  185. {
  186. if (_disposed) return Constant.EmptyString;
  187. var value = Value(rowIndex, columnName);
  188. return Text(value);
  189. }
  190. /// <summary>搜索默认表。</summary>
  191. /// <param name="conditionColumn">搜索条件:列名。</param>
  192. /// <param name="conditionValue">搜索条件:列值。</param>
  193. /// <param name="resultColumn">搜索结果。</param>
  194. public string Text(string conditionColumn, string conditionValue, string resultColumn)
  195. {
  196. if (_disposed) return Constant.EmptyString;
  197. var value = Value(conditionColumn, conditionValue, resultColumn);
  198. return Text(value);
  199. }
  200. /// <summary>搜索默认表。</summary>
  201. /// <param name="conditionColumn">搜索条件:列名。</param>
  202. /// <param name="conditionValue">搜索条件:列值。</param>
  203. /// <param name="resultColumn">搜索结果。</param>
  204. public string Text(int conditionColumn, string conditionValue, int resultColumn)
  205. {
  206. if (_disposed) return Constant.EmptyString;
  207. var value = Value(conditionColumn, conditionValue, resultColumn);
  208. return Text(value);
  209. }
  210. #endregion
  211. #region Value
  212. /// <summary>获取默认表中第 0 行、第 0 列的单元格内容。</summary>
  213. public object Value()
  214. {
  215. if (_disposed) return null;
  216. return Value(0, 0);
  217. }
  218. /// <summary>获取默认表中指定行中第 0 列的内容。</summary>
  219. /// <param name="rowIndex">行索引,从 0 开始。</param>
  220. public object Value(int rowIndex)
  221. {
  222. if (_disposed) return null;
  223. return Value(rowIndex, 0);
  224. }
  225. /// <summary>获取默认表中第 0 行指定列的内容。</summary>
  226. /// <param name="columnName">列名称。</param>
  227. public object Value(string columnName)
  228. {
  229. if (_disposed) return null;
  230. return Value(0, columnName);
  231. }
  232. /// <summary>获取默认表中指定单元格的内容。</summary>
  233. /// <param name="rowIndex">行索引,从 0 开始。</param>
  234. /// <param name="columnIndex">列索引,从 0 开始。</param>
  235. public object Value(int rowIndex, int columnIndex)
  236. {
  237. if (_disposed) return null;
  238. if (Table != null)
  239. {
  240. if (rowIndex >= 0 && rowIndex < Table.Rows.Count)
  241. {
  242. if (columnIndex >= 0 && columnIndex < Table.Columns.Count)
  243. {
  244. return Table.Rows[rowIndex][columnIndex];
  245. }
  246. }
  247. }
  248. return null;
  249. }
  250. /// <summary>获取默认表中指定单元的内容。</summary>
  251. /// <param name="rowIndex">行索引,从 0 开始。</param>
  252. /// <param name="columnName">列名称。</param>
  253. public object Value(int rowIndex, string columnName)
  254. {
  255. if (_disposed) return null;
  256. if ((Table != null) && !string.IsNullOrEmpty(columnName))
  257. {
  258. if ((rowIndex < Table.Rows.Count) && (rowIndex >= 0))
  259. {
  260. try { return Table.Rows[rowIndex][columnName]; }
  261. catch { }
  262. }
  263. }
  264. return null;
  265. }
  266. /// <summary>搜索默认表。</summary>
  267. /// <param name="conditionColumn">搜索条件:列名。</param>
  268. /// <param name="conditionValue">搜索条件:列值。</param>
  269. /// <param name="resultColumn">搜索结果。</param>
  270. public object Value(string conditionColumn, string conditionValue, string resultColumn)
  271. {
  272. if (_disposed) return null;
  273. if ((Table != null) && (!string.IsNullOrEmpty(conditionColumn)) && (conditionValue != null) && (!string.IsNullOrEmpty(resultColumn)))
  274. {
  275. for (int i = 0; i < Table.Rows.Count; i++)
  276. {
  277. try
  278. {
  279. if (Table.Rows[i][conditionColumn].ToString() == conditionValue) return Table.Rows[i][resultColumn];
  280. }
  281. catch { }
  282. }
  283. }
  284. return null;
  285. }
  286. /// <summary>搜索默认表。</summary>
  287. /// <param name="conditionColumn">搜索条件:列名。</param>
  288. /// <param name="conditionValue">搜索条件:列值。</param>
  289. /// <param name="resultColumn">搜索结果。</param>
  290. public object Value(int conditionColumn, string conditionValue, int resultColumn)
  291. {
  292. if (_disposed) return null;
  293. if ((Table != null) && (conditionColumn >= 0) && (conditionValue != null) && (resultColumn >= 0))
  294. {
  295. if ((conditionColumn < Table.Columns.Count) && (resultColumn < Table.Columns.Count))
  296. {
  297. for (int i = 0; i < Table.Rows.Count; i++)
  298. {
  299. try
  300. {
  301. if (Table.Rows[i][conditionColumn].ToString() == conditionValue) return Table.Rows[i][resultColumn];
  302. }
  303. catch { }
  304. }
  305. }
  306. }
  307. return null;
  308. }
  309. #endregion
  310. #region Method
  311. /// <summary>拆分表组,单独查询。</summary>
  312. public List<Query> Split()
  313. {
  314. var list = new List<Query>();
  315. if (_disposed) return list;
  316. foreach (var table in _tables)
  317. {
  318. if (table == null) continue;
  319. var query = new Query();
  320. query._success = true;
  321. query._tables.Add(table);
  322. list.Add(query);
  323. }
  324. return list;
  325. }
  326. /// <summary>添加数据表。</summary>
  327. public bool Add(DataTable tables)
  328. {
  329. if (_disposed) return false;
  330. if (tables == null) return false;
  331. _tables.Add(tables);
  332. return true;
  333. }
  334. /// <summary>添加数据表。</summary>
  335. public int Add(IEnumerable<DataTable> tables)
  336. {
  337. var count = 0;
  338. if (_disposed) return count;
  339. if (tables == null) return count;
  340. foreach (var table in tables)
  341. {
  342. if (table == null) continue;
  343. _tables.Add(table);
  344. count = count + 1;
  345. }
  346. return count;
  347. }
  348. /// <summary>清除所有表,并释放系统资源。</summary>
  349. public virtual void Clear()
  350. {
  351. if (_tables != null)
  352. {
  353. foreach (var table in _tables)
  354. {
  355. if (table != null)
  356. {
  357. try { table.Dispose(); } catch { }
  358. }
  359. }
  360. _tables.Clear();
  361. }
  362. if (_exception != null) _exception = null;
  363. _success = false;
  364. }
  365. /// <summary>释放系统资源。</summary>
  366. public virtual void Dispose()
  367. {
  368. Clear();
  369. _disposed = true;
  370. // GC.SuppressFinalize(this);
  371. }
  372. /// <summary></summary>
  373. /// <exception cref="Exception"></exception>
  374. public List<T> Fill<T>() where T : Record
  375. {
  376. var list = new List<T>();
  377. var type = typeof(T);
  378. for (int r = 0; r < Rows; r++)
  379. {
  380. var entity = type.Assembly.CreateInstance(type.FullName);
  381. var ts = TableStructure.ParseModel(type);
  382. var properties = type.GetProperties();
  383. foreach (var property in properties)
  384. {
  385. if (ts.Columns.ContainsKey(property.Name) == false) continue;
  386. var setter = property.GetSetMethod();
  387. if (setter == null) continue;
  388. var attribute = ts.Columns[property.Name];
  389. var pt = property.PropertyType;
  390. if (pt.Equals(typeof(object)) || pt.Equals(typeof(Nullable<DateTime>)))
  391. {
  392. setter.Invoke(entity, new object[] { Value(r, attribute.Field) });
  393. }
  394. else if (pt.Equals(typeof(DateTime)))
  395. {
  396. var value = Value(r, attribute.Field);
  397. if (value != null) setter.Invoke(entity, new object[] { Value(r, attribute.Field) });
  398. }
  399. else if (pt.Equals(typeof(byte[])))
  400. {
  401. setter.Invoke(entity, new object[] { (byte[])Value(r, attribute.Field) });
  402. }
  403. else if (pt.Equals(typeof(byte)))
  404. {
  405. setter.Invoke(entity, new object[] { TextConverter.GetByte(Text(r, attribute.Field)) });
  406. }
  407. else if (pt.Equals(typeof(sbyte)))
  408. {
  409. setter.Invoke(entity, new object[] { TextConverter.GetSByte(Text(r, attribute.Field)) });
  410. }
  411. else if (pt.Equals(typeof(short)))
  412. {
  413. setter.Invoke(entity, new object[] { TextConverter.GetInt16(Text(r, attribute.Field)) });
  414. }
  415. else if (pt.Equals(typeof(ushort)))
  416. {
  417. setter.Invoke(entity, new object[] { TextConverter.GetUInt16(Text(r, attribute.Field)) });
  418. }
  419. else if (pt.Equals(typeof(int)))
  420. {
  421. setter.Invoke(entity, new object[] { TextConverter.GetInt32(Text(r, attribute.Field)) });
  422. }
  423. else if (pt.Equals(typeof(uint)))
  424. {
  425. setter.Invoke(entity, new object[] { TextConverter.GetUInt32(Text(r, attribute.Field)) });
  426. }
  427. else if (pt.Equals(typeof(long)))
  428. {
  429. setter.Invoke(entity, new object[] { TextConverter.GetInt64(Text(r, attribute.Field)) });
  430. }
  431. else if (pt.Equals(typeof(ulong)))
  432. {
  433. setter.Invoke(entity, new object[] { TextConverter.GetUInt64(Text(r, attribute.Field)) });
  434. }
  435. else if (pt.Equals(typeof(float)))
  436. {
  437. setter.Invoke(entity, new object[] { TextConverter.GetSingle(Text(r, attribute.Field)) });
  438. }
  439. else if (pt.Equals(typeof(double)))
  440. {
  441. setter.Invoke(entity, new object[] { TextConverter.GetDouble(Text(r, attribute.Field)) });
  442. }
  443. else if (pt.Equals(typeof(decimal)))
  444. {
  445. setter.Invoke(entity, new object[] { TextConverter.GetDecimal(Text(r, attribute.Field)) });
  446. }
  447. else if (pt.Equals(typeof(string)))
  448. {
  449. setter.Invoke(entity, new object[] { Text(r, attribute.Field) });
  450. }
  451. else
  452. {
  453. try
  454. {
  455. setter.Invoke(entity, new object[] { Value(r, attribute.Field) });
  456. }
  457. catch { }
  458. }
  459. }
  460. list.Add((T)entity);
  461. }
  462. return list;
  463. }
  464. #endregion
  465. #region Static
  466. private static ObjectDisposedException DisposedException { get { return new ObjectDisposedException(typeof(Query).FullName); } }
  467. /// <summary>简单查询:取结果中第 0 列所有单元格的文本形式,可指定查询后关闭服务器连接,返回结果中不包含无效文本。</summary>
  468. public static List<string> SimpleColumn(IDatabase database, string statement, bool close = false)
  469. {
  470. var list = new List<string>();
  471. if (database == null) return list;
  472. if (!database.Connect()) return list;
  473. var query = database.Query(statement);
  474. for (int i = 0; i < query.Rows; i++)
  475. {
  476. var cell = TextModifier.Trim(query.Text(i));
  477. if (string.IsNullOrEmpty(cell)) continue;
  478. if (list.Contains(cell)) continue; ;
  479. list.Add(cell);
  480. }
  481. query.Dispose();
  482. if (close) database.Close();
  483. return list;
  484. }
  485. /// <summary>简单查询:取结果中第 0 行、第 0 列单元格中的文本,可指定查询后关闭服务器连接。</summary>
  486. public static string SimpleCell(IDatabase database, string statement, bool close = false)
  487. {
  488. if (database == null) return "";
  489. if (!database.Connect()) return "";
  490. var vquery = database.Query(statement);
  491. var vcell = TextModifier.Trim(vquery.Text());
  492. vquery.Dispose();
  493. if (close) database.Close();
  494. return vcell;
  495. }
  496. #endregion
  497. }
  498. }