IEnumerable <T> ForEachFirstCol <T>(IWrappedDataReader p_wrappedReader) { // yield无法使用await,无法在含catch的try内 // 一定要使用using 或 finally方式释放资源,不然foreach内部break时资源无法释放!!! try { using (p_wrappedReader) { MySqlDataReader reader = (MySqlDataReader)p_wrappedReader.Reader; var cols = reader.GetColumnSchema(); if (cols[0].DataType == typeof(T)) { while (reader.Read()) { yield return(reader.GetFieldValue <T>(0)); } } else { while (reader.Read()) { yield return((T)Convert.ChangeType(reader.GetValue(0), typeof(T))); } } } } finally { ReleaseConnection(); } }
IEnumerable <TRow> ForEachRow <TRow>(IWrappedDataReader p_wrappedReader) where TRow : Row { // yield无法使用await,无法在含catch的try内 // 一定要使用using 或 finally方式释放资源,不然foreach内部break时资源无法释放!!! try { using (p_wrappedReader) { MySqlDataReader reader = (MySqlDataReader)p_wrappedReader.Reader; var cols = reader.GetColumnSchema(); // Entity类型 Type tpEntity = null; if (typeof(TRow).IsSubclassOf(typeof(Entity))) { tpEntity = typeof(TRow); } while (reader.Read()) { // 无参数构造方法可能为private,如实体类型 TRow row = (TRow)Activator.CreateInstance(typeof(TRow), true); for (int i = 0; i < reader.FieldCount; i++) { var col = cols[i]; Type colType = col.DataType; if (col.AllowDBNull.HasValue && col.AllowDBNull.Value && col.DataType.IsValueType) { // 可为null的值类型 colType = typeof(Nullable <>).MakeGenericType(col.DataType); } else if (colType == typeof(byte) && tpEntity != null) { // Entity 时根据属性类型将 byte 自动转为 enum 类型 var prop = tpEntity.GetProperty(col.ColumnName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.IgnoreCase); if (prop != null) { colType = prop.PropertyType; } } if (reader.IsDBNull(i)) { new Cell(row, col.ColumnName, colType); } else { new Cell(row, col.ColumnName, colType, reader.GetValue(i)); } } yield return(row); } } } finally { ReleaseConnection(); } }