diff --git a/Apewer/Source/SourceUtility.cs b/Apewer/Source/SourceUtility.cs index c0ae115..49295ad 100644 --- a/Apewer/Source/SourceUtility.cs +++ b/Apewer/Source/SourceUtility.cs @@ -470,60 +470,80 @@ namespace Apewer.Source #region Query - /// 简单查询:取结果中第 0 列所有单元格的文本形式,可指定查询后关闭服务器连接,返回结果中不包含无效文本。 + /// 简单查询:取结果中第 0 列所有单元格的文本形式,返回结果中不包含无效文本和空文本。 /// 数据库客户端。 /// 用于查询的 SQL 语句。 /// SQL 参数。 /// - public static string[] Column(this IDbAdo source, string sql, object parameters = null) + public static string[] Column(this IDbAdo source, string sql, object parameters = null) => Column(source, sql, parameters, TextUtility.Text).FindAll(x => x.NotEmpty()); + + /// 简单查询:取结果中第 0 列所有单元格。 + /// 数据库客户端。 + /// 用于查询的 SQL 语句。 + /// SQL 参数。 + /// 获取单元格内容的程序。value 有可能是 NULL 值,需要 getter 自行处理。 + /// + /// + public static T[] Column(this IDbAdo source, string sql, object parameters, Func getter) { - if (source == null) return new string[0]; + if (source == null) throw new ArgumentNullException(nameof(source)); + if (sql.IsEmpty()) throw new ArgumentNullException(nameof(sql)); + if (getter == null) throw new ArgumentNullException(nameof(getter)); - var pool = null as string[]; - var rows = 0; - var count = 0; using (var query = source.Query(sql, parameters)) { + if (query == null) throw new SqlException("方法 IDbAdo.Query 返回了 NULL 值。"); if (!query.Success) throw new SqlException(query, sql); - rows = query.Rows; - if (rows < 1) return new string[0]; + var rows = query.Rows; + if (rows < 1) return new T[0]; - pool = new string[rows]; + var list = new List(); + list.Capacity = rows; for (int i = 0; i < rows; i++) { - var cell = TextUtility.Trim(query.Text(i, 0)); - if (string.IsNullOrEmpty(cell)) continue; + var value = query.Value(i, 0); + if (value != null && value.Equals(DBNull.Value)) value = null; - pool[count] = cell; - count++; + // 此处 value 有可能是 null + var item = getter.Invoke(value); + list.Add(item); } + return list.ToArray(); } - - if (count < 1) return new string[0]; - if (count == rows) return pool; - - var array = new string[count]; - Array.Copy(pool, 0, array, 0, count); - return array; } - /// 简单查询:取结果中第 0 行、第 0 列单元格中的文本,可指定查询后关闭服务器连接。 - /// 数据库客户端。 + /// 简单查询:取结果中第 0 行、第 0 列单元格中的文本。 + /// 数据库客户端。 /// 用于查询的 SQL 语句。 /// SQL 参数。 /// /// - public static string Cell(this IDbAdo dbClient, string sql, object parameters = null) + public static string Cell(this IDbAdo source, string sql, object parameters = null) => Cell(source, sql, parameters, TextUtility.Text); + + /// 简单查询:取结果中第 0 行、第 0 列单元格。 + /// 数据库客户端。 + /// 用于查询的 SQL 语句。 + /// SQL 参数。 + /// 获取单元格内容的程序。value 有可能是 NULL 值,需要 getter 自行处理。 + /// + /// + public static T Cell(this IDbAdo source, string sql, object parameters, Func getter) { - if (dbClient == null) throw new ArgumentNullException(nameof(dbClient)); + if (source == null) throw new ArgumentNullException(nameof(source)); if (sql.IsEmpty()) throw new ArgumentNullException(nameof(sql)); + if (getter == null) throw new ArgumentNullException(nameof(getter)); - using (var query = dbClient.Query(sql, parameters)) + using (var query = source.Query(sql, parameters)) { + if (query == null) throw new SqlException("方法 IDbAdo.Query 返回了 NULL 值。"); if (!query.Success) throw new SqlException(query, sql); - var value = TextUtility.Trim(query.Text(0, 0)); - return value; + var value = query.Value(0, 0); + if (value != null && value.Equals(DBNull.Value)) value = null; + + // 此处 value 有可能是 null + var result = getter.Invoke(value); + return result; } }