using Apewer; using Apewer.Internals; using System; using System.Collections.Generic; using System.Data; namespace Apewer.Source { /// <summary>查询数据表。</summary> public class Query : IQuery, IDisposable { private bool _disposed = false; private bool _success = false; private string _error = ""; private string _message = ""; private Exception _exception = null; private List<DataTable> _tables = new List<DataTable>(); #region Property /// <summary>语句执行成功。</summary> public bool Success { get { if (_disposed) return false; return _success; } set { if (_disposed) return; _success = value; } } /// <summary>错误信息。</summary> public string Error { get { if (_disposed) return ""; if (!string.IsNullOrEmpty(_error)) return _error; if (_exception == null) return ""; var error = ""; try { error = _exception.Message; } finally { } return error; } set { if (_disposed) return; _error = value ?? ""; } } /// <summary>消息。</summary> public string Message { get { if (_disposed) return ""; return _message ?? ""; } set { if (_disposed) return; _message = value ?? ""; } } /// <summary>语句执行失败时的 Exception 对象。</summary> public Exception Exception { get { if (_disposed) return null; return _exception; } set { if (_disposed) return; _exception = value; } } /// <summary>所有结果表。</summary> public List<DataTable> Tables { get { if (_disposed) return new List<DataTable>(); return _tables; } } /// <summary>获取默认结果表。如果设置默认结果表,会丢失设置前的所有结果表。</summary> public DataTable Table { get { if (_disposed) return null; if (_tables.Count < 1) return null; return _tables[0]; } set { if (_disposed) return; Clear(); if (_disposed) return; _tables.Add(value); } } /// <summary>所有表中不含内容行。</summary> public bool Empty { get { if (_disposed) return true; if (_tables.Count < 1) return true; foreach (var table in _tables) { if (table == null) continue; try { if (table.Rows.Count > 0) return false; } finally { } } return true; } } /// <summary>默认表中的数据总行数。</summary> public int Rows { get { if (_disposed) return 0; if (Table != null) return Table.Rows.Count; else return 0; } } /// <summary>默认表中的数据总列数。</summary> public int Columns { get { if (_disposed) return 0; if (Table != null) return Table.Columns.Count; else return 0; } } #endregion #region Text private string Text(object value) { var result = Constant.EmptyString; if (value != null) { if (!value.Equals(DBNull.Value)) { try { result = value.ToString(); } finally { } } } return result; } /// <summary>获取默认表中第 0 行、第 0 列的单元格内容。</summary> public string Text() { if (_disposed) return Constant.EmptyString; var value = Value(); return Text(value); } /// <summary>获取默认表中指定行中第 0 列的内容。</summary> /// <param name="rowIndex">行索引,从 0 开始。</param> public string Text(int rowIndex) { if (_disposed) return Constant.EmptyString; var value = Value(rowIndex); return Text(value); } /// <summary>获取默认表中第 0 行指定列的内容。</summary> /// <param name="columnName">列名称。</param> public string Text(string columnName) { if (_disposed) return Constant.EmptyString; var value = Value(columnName); return Text(value); } /// <summary>获取默认表中指定单元格的内容。</summary> /// <param name="rowIndex">行索引,从 0 开始。</param> /// <param name="columnIndex">列索引,从 0 开始。</param> public string Text(int rowIndex, int columnIndex) { if (_disposed) return Constant.EmptyString; var value = Value(rowIndex, columnIndex); return Text(value); } /// <summary>获取默认表中指定单元的内容。</summary> /// <param name="rowIndex">行索引,从 0 开始。</param> /// <param name="columnName">列名称。</param> public string Text(int rowIndex, string columnName) { if (_disposed) return Constant.EmptyString; var value = Value(rowIndex, columnName); return Text(value); } /// <summary>搜索默认表。</summary> /// <param name="conditionColumn">搜索条件:列名。</param> /// <param name="conditionValue">搜索条件:列值。</param> /// <param name="resultColumn">搜索结果。</param> public string Text(string conditionColumn, string conditionValue, string resultColumn) { if (_disposed) return Constant.EmptyString; var value = Value(conditionColumn, conditionValue, resultColumn); return Text(value); } /// <summary>搜索默认表。</summary> /// <param name="conditionColumn">搜索条件:列名。</param> /// <param name="conditionValue">搜索条件:列值。</param> /// <param name="resultColumn">搜索结果。</param> public string Text(int conditionColumn, string conditionValue, int resultColumn) { if (_disposed) return Constant.EmptyString; var value = Value(conditionColumn, conditionValue, resultColumn); return Text(value); } #endregion #region Value /// <summary>获取默认表中第 0 行、第 0 列的单元格内容。</summary> public object Value() { if (_disposed) return null; return Value(0, 0); } /// <summary>获取默认表中指定行中第 0 列的内容。</summary> /// <param name="rowIndex">行索引,从 0 开始。</param> public object Value(int rowIndex) { if (_disposed) return null; return Value(rowIndex, 0); } /// <summary>获取默认表中第 0 行指定列的内容。</summary> /// <param name="columnName">列名称。</param> public object Value(string columnName) { if (_disposed) return null; return Value(0, columnName); } /// <summary>获取默认表中指定单元格的内容。</summary> /// <param name="rowIndex">行索引,从 0 开始。</param> /// <param name="columnIndex">列索引,从 0 开始。</param> public object Value(int rowIndex, int columnIndex) { if (_disposed) return null; if (Table != null) { if (rowIndex >= 0 && rowIndex < Table.Rows.Count) { if (columnIndex >= 0 && columnIndex < Table.Columns.Count) { return Table.Rows[rowIndex][columnIndex]; } } } return null; } /// <summary>获取默认表中指定单元的内容。</summary> /// <param name="rowIndex">行索引,从 0 开始。</param> /// <param name="columnName">列名称。</param> public object Value(int rowIndex, string columnName) { if (_disposed) return null; if ((Table != null) && !string.IsNullOrEmpty(columnName)) { if ((rowIndex < Table.Rows.Count) && (rowIndex >= 0)) { try { return Table.Rows[rowIndex][columnName]; } catch { } } } return null; } /// <summary>搜索默认表。</summary> /// <param name="conditionColumn">搜索条件:列名。</param> /// <param name="conditionValue">搜索条件:列值。</param> /// <param name="resultColumn">搜索结果。</param> public object Value(string conditionColumn, string conditionValue, string resultColumn) { if (_disposed) return null; if ((Table != null) && (!string.IsNullOrEmpty(conditionColumn)) && (conditionValue != null) && (!string.IsNullOrEmpty(resultColumn))) { for (int i = 0; i < Table.Rows.Count; i++) { try { if (Table.Rows[i][conditionColumn].ToString() == conditionValue) return Table.Rows[i][resultColumn]; } catch { } } } return null; } /// <summary>搜索默认表。</summary> /// <param name="conditionColumn">搜索条件:列名。</param> /// <param name="conditionValue">搜索条件:列值。</param> /// <param name="resultColumn">搜索结果。</param> public object Value(int conditionColumn, string conditionValue, int resultColumn) { if (_disposed) return null; if ((Table != null) && (conditionColumn >= 0) && (conditionValue != null) && (resultColumn >= 0)) { if ((conditionColumn < Table.Columns.Count) && (resultColumn < Table.Columns.Count)) { for (int i = 0; i < Table.Rows.Count; i++) { try { if (Table.Rows[i][conditionColumn].ToString() == conditionValue) return Table.Rows[i][resultColumn]; } catch { } } } } return null; } #endregion #region Method /// <summary>拆分表组,单独查询。</summary> public List<Query> Split() { var list = new List<Query>(); if (_disposed) return list; foreach (var table in _tables) { if (table == null) continue; var query = new Query(); query._success = true; query._tables.Add(table); list.Add(query); } return list; } /// <summary>添加数据表。</summary> public bool Add(DataTable tables) { if (_disposed) return false; if (tables == null) return false; _tables.Add(tables); return true; } /// <summary>添加数据表。</summary> public int Add(IEnumerable<DataTable> tables) { var count = 0; if (_disposed) return count; if (tables == null) return count; foreach (var table in tables) { if (table == null) continue; _tables.Add(table); count = count + 1; } return count; } /// <summary>清除所有表,并释放系统资源。</summary> public virtual void Clear() { if (_tables != null) { foreach (var table in _tables) { if (table != null) { try { table.Dispose(); } catch { } } } _tables.Clear(); } if (_exception != null) _exception = null; _success = false; } /// <summary>释放系统资源。</summary> public virtual void Dispose() { Clear(); _disposed = true; // GC.SuppressFinalize(this); } /// <summary></summary> /// <exception cref="Exception"></exception> public List<T> Fill<T>() where T : Record { var list = new List<T>(); var type = typeof(T); for (int r = 0; r < Rows; r++) { var entity = type.Assembly.CreateInstance(type.FullName); var ts = TableStructure.ParseModel(type); var properties = type.GetProperties(); foreach (var property in properties) { if (ts.Columns.ContainsKey(property.Name) == false) continue; var setter = property.GetSetMethod(); if (setter == null) continue; var attribute = ts.Columns[property.Name]; var pt = property.PropertyType; if (pt.Equals(typeof(object)) || pt.Equals(typeof(Nullable<DateTime>))) { setter.Invoke(entity, new object[] { Value(r, attribute.Field) }); } else if (pt.Equals(typeof(DateTime))) { var value = Value(r, attribute.Field); if (value != null) setter.Invoke(entity, new object[] { Value(r, attribute.Field) }); } else if (pt.Equals(typeof(byte[]))) { setter.Invoke(entity, new object[] { (byte[])Value(r, attribute.Field) }); } else if (pt.Equals(typeof(byte))) { setter.Invoke(entity, new object[] { TextConverter.GetByte(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(sbyte))) { setter.Invoke(entity, new object[] { TextConverter.GetSByte(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(short))) { setter.Invoke(entity, new object[] { TextConverter.GetInt16(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(ushort))) { setter.Invoke(entity, new object[] { TextConverter.GetUInt16(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(int))) { setter.Invoke(entity, new object[] { TextConverter.GetInt32(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(uint))) { setter.Invoke(entity, new object[] { TextConverter.GetUInt32(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(long))) { setter.Invoke(entity, new object[] { TextConverter.GetInt64(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(ulong))) { setter.Invoke(entity, new object[] { TextConverter.GetUInt64(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(float))) { setter.Invoke(entity, new object[] { TextConverter.GetSingle(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(double))) { setter.Invoke(entity, new object[] { TextConverter.GetDouble(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(decimal))) { setter.Invoke(entity, new object[] { TextConverter.GetDecimal(Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(string))) { setter.Invoke(entity, new object[] { Text(r, attribute.Field) }); } else { try { setter.Invoke(entity, new object[] { Value(r, attribute.Field) }); } catch { } } } list.Add((T)entity); } return list; } #endregion #region Static private static ObjectDisposedException DisposedException { get { return new ObjectDisposedException(typeof(Query).FullName); } } /// <summary>简单查询:取结果中第 0 列所有单元格的文本形式,可指定查询后关闭服务器连接,返回结果中不包含无效文本。</summary> public static List<string> SimpleColumn(IDatabase database, string statement, bool close = false) { var list = new List<string>(); if (database == null) return list; if (!database.Connect()) return list; var query = database.Query(statement); for (int i = 0; i < query.Rows; i++) { var cell = TextModifier.Trim(query.Text(i)); if (string.IsNullOrEmpty(cell)) continue; if (list.Contains(cell)) continue; ; list.Add(cell); } query.Dispose(); if (close) database.Close(); return list; } /// <summary>简单查询:取结果中第 0 行、第 0 列单元格中的文本,可指定查询后关闭服务器连接。</summary> public static string SimpleCell(IDatabase database, string statement, bool close = false) { if (database == null) return ""; if (!database.Connect()) return ""; var vquery = database.Query(statement); var vcell = TextModifier.Trim(vquery.Text()); vquery.Dispose(); if (close) database.Close(); return vcell; } #endregion } }