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.

197 lines
6.8 KiB

4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
2 years ago
3 years ago
2 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
2 years ago
4 years ago
4 years ago
4 years ago
  1. using Apewer.Internals;
  2. using Newtonsoft.Json.Linq;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Data;
  6. using static Apewer.TextUtility;
  7. namespace Apewer.Source
  8. {
  9. /// <summary>System.Data.DataTable 装箱查询。</summary>
  10. public sealed class Query : IQuery, IDisposable, IToJson
  11. {
  12. private bool _disposed = false;
  13. private bool _success = false;
  14. private string _message = null;
  15. private DataTable _table = null;
  16. private DataTable[] _tables = null;
  17. /// <summary>创建实例,默认状态为失败。</summary>
  18. public Query(bool success = false, string message = null)
  19. {
  20. _success = false;
  21. _message = message;
  22. }
  23. /// <summary>创建实例,Exception 为 NULL 时成功,非 NULL 时失败。</summary>
  24. public Query(Exception exception)
  25. {
  26. _success = exception == null;
  27. _message = RuntimeUtility.Message(exception);
  28. }
  29. /// <summary>创建实例,包装一个 DataTable 对象,数据表为 NULL 时失败,非 NULL 时成功。</summary>
  30. public Query(DataTable table)
  31. {
  32. _table = table;
  33. _success = table != null;
  34. _message = table == null ? "未获取有效的数据表。" : null;
  35. }
  36. /// <summary>创建实例,包装一个 DataTable 对象。</summary>
  37. public Query(DataTable table, bool success, string message = null)
  38. {
  39. _table = table;
  40. _success = success;
  41. _message = message;
  42. }
  43. /// <summary>创建实例,包装多个 DataTable 对象。</summary>
  44. public Query(DataTable[] tables, bool success = true, string message = null)
  45. {
  46. _tables = tables;
  47. _success = success;
  48. _message = message;
  49. if (tables != null && tables.Length > 0) _table = tables[0];
  50. }
  51. /// <summary>从 <see cref="Query"/> 到 <see cref="Boolean"/> 的隐式转换,判断 <see cref="Query"/> 执行成功且包含表。</summary>
  52. public static implicit operator bool(Query query) => query != null && query.Success && query.Table != null;
  53. /// <summary>从 <see cref="DataTable"/> 到 <see cref="Query"/> 的隐式转换。</summary>
  54. public static implicit operator Query(DataTable table) => new Query(table, table != null, null);
  55. /// <summary>从 <see cref="Query"/> 到 <see cref="DataTable"/> 的隐式转换。</summary>
  56. public static implicit operator DataTable(Query query) => query?.Table;
  57. #region Property
  58. /// <summary>语句执行成功。</summary>
  59. public bool Success { get => _success; }
  60. /// <summary>消息。</summary>
  61. public string Message { get => _message; }
  62. /// <summary>所有结果表。</summary>
  63. public DataTable[] Tables { get => _tables; }
  64. /// <summary>获取默认结果表。如果设置默认结果表,会丢失设置前的所有结果表。</summary>
  65. public DataTable Table { get => _table; }
  66. /// <summary>默认表中的数据总行数。</summary>
  67. public int Rows { get => _table == null ? 0 : _table.Rows.Count; }
  68. /// <summary>默认表中的数据总列数。</summary>
  69. public int Columns { get => _table == null ? 0 : _table.Columns.Count; }
  70. #endregion
  71. #region Value
  72. /// <summary>获取默认表中指定单元格的内容。</summary>
  73. /// <param name="rowIndex">行索引,从 0 开始。</param>
  74. /// <param name="columnIndex">列索引,从 0 开始。</param>
  75. public object Value(int rowIndex, int columnIndex) => Table.Value(rowIndex, columnIndex);
  76. /// <summary>获取默认表中指定单元的内容。</summary>
  77. /// <param name="rowIndex">行索引,从 0 开始。</param>
  78. /// <param name="columnName">列名称/字段名称,此名称不区分大小写。</param>
  79. public object Value(int rowIndex, string columnName) => Table.Value(rowIndex, columnName);
  80. #endregion
  81. #region Method
  82. /// <summary>释放系统资源。</summary>
  83. public void Dispose()
  84. {
  85. if (_disposed) return;
  86. if (_tables != null)
  87. {
  88. foreach (var table in _tables) RuntimeUtility.Dispose(table);
  89. _tables = null;
  90. }
  91. RuntimeUtility.Dispose(_table);
  92. _table = null;
  93. _tables = null;
  94. _disposed = true;
  95. // GC.SuppressFinalize(this);
  96. }
  97. #endregion
  98. #region 模型化、IToJson
  99. /// <summary>转换为 Json 对象。</summary>
  100. public Json ToJson()
  101. {
  102. var jsonObject = Json.NewObject();
  103. jsonObject.SetProperty("success", _success);
  104. jsonObject.SetProperty("message", _message);
  105. if (Table != null)
  106. {
  107. var columns = SourceUtility.ToJson(Table.Columns);
  108. jsonObject.SetProperty("columns", columns);
  109. var rows = SourceUtility.ToJson(Table.Rows);
  110. jsonObject.SetProperty("rows", rows);
  111. }
  112. return jsonObject;
  113. }
  114. /// <summary>转换为模型数组。</summary>
  115. public ObjectSet[] ToArray()
  116. {
  117. var oss = null as ObjectSet[];
  118. var table = _table;
  119. if (!_disposed && table != null)
  120. {
  121. var width = table.Columns.Count;
  122. var names = new string[width];
  123. for (var c = 0; c < width; c++)
  124. {
  125. var name = table.Columns[c].ColumnName;
  126. if (name.IsEmpty()) continue;
  127. if (names.Contains(name)) continue;
  128. names[c] = name;
  129. }
  130. var unnamed = 1;
  131. for (var c = 0; c < width; c++)
  132. {
  133. if (names[c] != null) continue;
  134. while (true)
  135. {
  136. var name = "unnamed_" + unnamed.ToString();
  137. unnamed++;
  138. if (names.Contains(name)) continue;
  139. names[c] = name;
  140. break;
  141. }
  142. }
  143. var height = table.Rows.Count;
  144. oss = new ObjectSet[height];
  145. for (var r = 0; r < height; r++)
  146. {
  147. var os = new ObjectSet();
  148. var dict = os.Origin;
  149. for (var c = 0; c < width; c++)
  150. {
  151. var v = Value(r, c);
  152. dict.Add(names[c], v.IsNull() ? null : v);
  153. }
  154. oss[r] = os;
  155. }
  156. }
  157. return oss;
  158. }
  159. #endregion
  160. }
  161. }