using System; using System.Collections.Generic; using System.Text; using static Apewer.NumberUtility; namespace Apewer.Source { /// ORM 帮助程序。 public static class OrmHelper { #region As private static List As(List input) where T : IRecord { if (input == null) return null; var output = new List(input.Count); foreach (var record in input) { if (record == null) continue; var t = (T)record; output.Add(t); } return output; } private static Result As(Result input) where T : class, IRecord, new() { if (input == null) return null; if (!input.HasValue) return new Result(input.Code, input.Message); var value = input.Value as T; return new Result(value); } private static Result> As(Result> input) where T : class, IRecord, new() { if (input == null) return null; if (!input.HasValue) return new Result>(input.Code, input.Message); var list = new List(input.Value.Count); foreach (var inputItem in input.Value) { var value = inputItem as T; list.Add(value); } return new Result>(list); } #endregion #region IQuery -> IRecord /// 读取所有行,生成列表。 public static List Fill(IQuery query) where T : class, IRecord, new() => As(Fill(query, typeof(T))); /// 读取所有行填充到 T,组成 List<T>。 /// public static List Fill(IQuery query, Type model) { if (query == null) return new List(); if (model == null) return new List(); var list = new List(query.Rows); var ts = TableStructure.ParseModel(model); for (int r = 0; r < query.Rows; r++) { var record = Row(query, r, model, ts); if (record != null) list.Add(record); } list.Capacity = list.Count; return list; } /// 获取指定列的所有值,无效值不加入结果。 /// public static List Column(IQuery query, Func filler) { if (query == null) throw new ArgumentNullException(nameof(query)); if (filler == null) throw new ArgumentNullException(nameof(filler)); var rows = query.Rows; var list = new List(rows); if (rows > 0) { list.Capacity = rows; var added = 0; for (int r = 0; r < rows; r++) { var value = filler(r); if (value == null) continue; if (value is string) { var valueString = value as string; if (string.IsNullOrEmpty(valueString)) continue; } list.Add(value); added++; } list.Capacity = added; } return list; } /// 填充指定行为记录实体。 /// 填充失败时返回 NULL 值。 /// /// /// public static IRecord Row(IQuery query, int rowIndex, Type model, TableStructure structure) { if (query == null) throw new ArgumentNullException(nameof(query)); if (model == null) throw new ArgumentNullException(nameof(model)); if (structure == null) throw new ArgumentNullException(nameof(structure)); if (rowIndex < 0 || rowIndex >= query.Rows) throw new ArgumentOutOfRangeException(nameof(rowIndex)); var record = Activator.CreateInstance(model); var properties = model.GetProperties(); var ts = structure; var r = rowIndex; 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))) { setter.Invoke(record, new object[] { query.Value(r, attribute.Field) }); } else if (pt.Equals(typeof(DateTime))) { var value = query.Value(r, attribute.Field); if (value != null) setter.Invoke(record, new object[] { query.Value(r, attribute.Field) }); } else if (pt.Equals(typeof(byte[]))) { setter.Invoke(record, new object[] { (byte[])query.Value(r, attribute.Field) }); } else if (pt.Equals(typeof(byte))) { setter.Invoke(record, new object[] { Byte(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(sbyte))) { setter.Invoke(record, new object[] { SByte(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(short))) { setter.Invoke(record, new object[] { Int16(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(ushort))) { setter.Invoke(record, new object[] { UInt16(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(int))) { setter.Invoke(record, new object[] { Int32(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(uint))) { setter.Invoke(record, new object[] { UInt32(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(long))) { setter.Invoke(record, new object[] { Int64(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(ulong))) { setter.Invoke(record, new object[] { UInt64(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(float))) { setter.Invoke(record, new object[] { Single(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(double))) { setter.Invoke(record, new object[] { Double(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(decimal))) { setter.Invoke(record, new object[] { Decimal(query.Text(r, attribute.Field)) }); } else if (pt.Equals(typeof(string))) { setter.Invoke(record, new object[] { query.Text(r, attribute.Field) }); } else { try { setter.Invoke(record, new object[] { query.Value(r, attribute.Field) }); } catch { } } } var iRecord = record as IRecord; return iRecord; } #endregion #region IOrm /// 查询记录。 /// 数据库对象。 /// 记录模型。 /// SQL 语句。 public static Result> Query(IDatabaseQuery database, Type model, string sql) { if (database == null) return new Result>("数据库无效。"); if (model == null) return new Result>("模型类型无效。"); if (string.IsNullOrEmpty(sql)) return new Result>("SQL 语句无效。"); using (var query = database.Query(sql) as Query) { if (query == null) return new Result>("查询实例无效。"); if (query.Exception != null) return new Result>(query.Exception); try { var list = Fill(query, model); return new Result>(list); } catch (Exception ex) { return new Result>(ex); } } } /// 查询记录。 /// 记录模型。 /// 数据库对象。 /// SQL 语句。 public static Result> Query(IDatabaseQuery database, string sql) where T : class, IRecord, new() => As(Query(database, typeof(T), sql)); /// 查询记录。 /// 数据库对象。 /// 记录模型。 /// 生成 SQL 语句的函数,传入参数为表名。 public static Result> Query(IDatabaseQuery database, Type model, Func sqlGetter) { if (sqlGetter == null) return new Result>("SQL 语句获取函数无效。"); try { var tableName = TableStructure.ParseModel(model).Table; if (string.IsNullOrEmpty(tableName)) return new Result>("表名无效。"); return Query(database, model, sqlGetter(tableName)); } catch (Exception ex) { return new Result>(ex); } } /// 查询记录。 /// 记录模型。 /// 数据库对象。 /// 生成 SQL 语句的函数,传入参数为表名。 public static Result> Query(IDatabaseQuery database, Func sqlGetter) where T : class, IRecord, new() => As(Query(database, typeof(T), sqlGetter)); /// 获取具有指定主键的记录。 /// 数据库对象。 /// 记录模型。 /// 主键。 /// 生成 SQL 语句的函数,传入参数为表名和主键值。 public static Result Get(IDatabaseQuery database, Type model, string key, Func sqlGetter) { if (sqlGetter == null) return new Result("SQL 语句获取函数无效。"); var safetyKey = TextUtility.SafeKey(key); if (string.IsNullOrEmpty(safetyKey)) return new Result("主键无效。"); var query = null as IQuery; var record = null as IRecord; try { var ts = TableStructure.ParseModel(model); var tableName = ts.Table; if (string.IsNullOrEmpty(tableName)) return new Result("表名无效。"); var sql = sqlGetter(tableName, safetyKey); query = database.Query(sql); if (query.Table == null) return new Result("没有获取到记录。"); record = Row(query, 0, model, ts); } catch (Exception ex) { RuntimeUtility.Dispose(query); return new Result(ex); } RuntimeUtility.Dispose(query); if (record == null) return new Result("没有获取到记录。"); return new Result(record); } /// 获取具有指定主键的记录。 /// 记录模型。 /// 数据库对象。 /// 主键。 /// 生成 SQL 语句的函数,传入参数为表名和主键值。 public static Result Get(IDatabaseQuery database, string key, Func sqlGetter) where T : class, IRecord, new() => As(Get(database, typeof(T), key, sqlGetter)); /// 获取主键。 /// 数据库对象。 /// 记录模型。 /// 生成 SQL 语句的函数,传入参数为表名。 public static Result> Keys(IDatabaseQuery database, Type model, Func sqlGetter) { if (database == null) return new Result>("数据库无效。"); if (model == null) return new Result>("模型类型无效。"); if (sqlGetter == null) return new Result>("SQL 语句获取函数无效。"); var tableStructure = null as TableStructure; try { tableStructure = TableStructure.ParseModel(model); } catch (Exception ex) { return new Result>(ex); } var tableName = tableStructure.Table; if (string.IsNullOrEmpty(tableName)) return new Result>("表名无效。"); // var keyName = null as string; // foreach (var column in tableStructure.Columns) // { // if (column.Key == "Key") // { // keyName = column.Value.Field; // break; // } // } // if (string.IsNullOrEmpty(keyName)) return Result>.Error("主键字段无效。"); // var sql = sqlGetter(tableName, keyName); var sql = sqlGetter(tableName); var query = null as IQuery; try { query = database.Query(sql); if (query == null) return new Result>("查询实例无效。"); var list = new List(query.Rows); for (var r = 0; r < query.Rows; r++) { var key = TextUtility.SafeKey(query.Text(r)); if (string.IsNullOrEmpty(key)) continue; list.Add(key); } query.Dispose(); list.Capacity = list.Count; return new Result>(list); } catch (Exception ex) { RuntimeUtility.Dispose(query); return new Result>(ex); } } /// 获取主键。 /// 记录模型。 /// 数据库对象。 /// 生成 SQL 语句的函数,传入参数为表名。 public static Result> Keys(IDatabaseQuery database, Func sqlGetter) where T : IRecord { return Keys(database, typeof(T), sqlGetter); } #endregion } }