/// <summary> /// Reads the first column of each row from the query result into a <see cref="HashSet{T}"/>. All other columns are ignored. /// <para>Valid <typeparamref name="T"/> types: Any .NET built-in type or ADO.NET data provider supported type.</para> /// </summary> /// <remarks> /// Note: <see cref="DBNull"/> values will be excluded. /// </remarks> /// <typeparam name="T">The generic type to use.</typeparam> /// <param name="odr">The <see cref="DbDataReader"/> to use.</param> /// <param name="token">The <see cref="CancellationToken"/> to use. (Optional)</param> /// <returns>The <see cref="HashSet{T}"/>.</returns> /// <exception cref="System.InvalidCastException">Thrown when <typeparamref name="T"/> is not supported.</exception> public static HashSet <T> ToHashSet <T>(this DbDataReader odr, CancellationToken token = default) { HashSet <T> projectedData = new HashSet <T>(); if (odr.HasRows) { Type tType = typeof(T); Type nonNullableObjType = tType.IsValueType ? (Nullable.GetUnderlyingType(tType) ?? tType) : tType; while (odr.Read()) { if (token.IsCancellationRequested) { return(projectedData); } object value = odr.GetValue(0); if (value != DBNull.Value) { projectedData.Add((T)(DbConnectorUtilities.ThrowIfFailedToMatchColumnType(tType, nonNullableObjType, value, () => odr.GetName(0)))); } } } return(projectedData); }
internal static OrdinalColumnMapLite[] GetOrdinalColumnNamesLite(this DbDataReader odr, IColumnMapSetting settings = null) { if (settings == null || (!settings.HasNamesToInclude && !settings.HasNamesToExclude)) { var ordinalColumnMap = new OrdinalColumnMapLite[odr.FieldCount]; for (int i = 0; i < odr.FieldCount; i++) { ordinalColumnMap[i] = new OrdinalColumnMapLite { Ordinal = i, Name = odr.GetName(i) }; } return(ordinalColumnMap); } else { bool hasNamesToInclude = settings.HasNamesToInclude; bool hasNamesToExclude = settings.HasNamesToExclude; var tempMap = new Queue <OrdinalColumnMapLite>(odr.FieldCount); for (int i = 0; i < odr.FieldCount; i++) { string colName = odr.GetName(i); if (!DbConnectorUtilities.IsColumnNameExcluded(colName, hasNamesToInclude, hasNamesToExclude, settings)) { tempMap.Enqueue(new OrdinalColumnMapLite { Ordinal = i, Name = colName }); } } if (tempMap.Count > 0) { var ordinalColumnMap = new OrdinalColumnMapLite[tempMap.Count]; for (int i = 0; tempMap.Count > 0; i++) { ordinalColumnMap[i] = tempMap.Dequeue(); } return(ordinalColumnMap); } else { return(null); } } }
private static object GetMappedParentObject(this DbDataReader odr, object obj, IEnumerable <ColumnMap> columnMaps) { foreach (var map in columnMaps) { if (map.IsChildMap) { odr.SetParentProperties(obj, map.ParentMap); } else { DbConnectorUtilities.SetChildProperty(obj, map, odr.GetValue(map.Column.Ordinal)); } } return(obj); }
public static object GetMappedObject(this DbDataReader odr, Type objType, IEnumerable <ColumnMap> columnMaps) { object obj = Activator.CreateInstance(objType); foreach (var map in columnMaps) { if (map.IsChildMap) { odr.SetParentProperties(obj, map.ParentMap); } else { DbConnectorUtilities.SetChildProperty(obj, map, odr.GetValue(map.Column.Ordinal)); } } return(obj); }
/// <summary> /// Reads data into a <see cref="List{T}"/>. /// <para>Valid <typeparamref name="T"/> types: <see cref="DataSet"/>, <see cref="DataTable"/>, <see cref="Dictionary{string,object}"/>, any .NET built-in type, or any struct or class with a parameterless constructor not assignable from <see cref="System.Collections.IEnumerable"/> (Note: only properties will be mapped).</para> /// </summary> /// <typeparam name="T">The generic type to use.</typeparam> /// <param name="odr">The <see cref="DbDataReader"/> to use.</param> /// <param name="token">The <see cref="CancellationToken"/> to use. (Optional)</param> /// <param name="cmd">The <see cref="IDbJobCommand"/> to use for data projection and caching. (Optional)</param> /// <returns>The <see cref="List{T}"/>.</returns> /// <exception cref="System.InvalidCastException">Thrown when <typeparamref name="T"/> is missing a parameterless constructor.</exception> /// <exception cref="System.InvalidCastException">Thrown when <typeparamref name="T"/> is assignable from <see cref="System.Collections.IEnumerable"/>.</exception> public static List <T> ToList <T>(this DbDataReader odr, CancellationToken token = default, IDbJobCommand cmd = null) { List <T> projectedData = new List <T>(); if (odr.HasRows) { Type tType = typeof(T); if (!DbConnectorUtilities._directTypeMap.Contains(tType) && !(tType.IsValueType && (tType.IsEnum || (Nullable.GetUnderlyingType(tType)?.IsEnum ?? false))) && !tType.IsArray) { //Dynamic MSIL cached version is around 30% faster and uses up to 57% less memory. if (cmd != null && (cmd.Flags & DbJobCommandFlags.NoCache) == DbJobCommandFlags.None) { ColumnMapCacheModel cacheModel = new ColumnMapCacheModel(tType, cmd, odr.GetOrdinalColumnNamesHash()); if (!DbConnectorCache.TryGetColumnMap(cacheModel, out IDynamicColumnMapper mapper)) { mapper = DynamicColumnMapper.CreateMapper <T>(odr.GetOrdinalColumnNames(cmd.MapSettings), cmd.MapSettings); DbConnectorCache.SetColumnMap(cacheModel, mapper); } var genericMapper = mapper as DynamicColumnMapper <T>; while (odr.Read()) { if (token.IsCancellationRequested) { return(projectedData); } projectedData.Add(genericMapper.OnBuild(odr)); } } else { if (typeof(IEnumerable).IsAssignableFrom(tType)) { throw new InvalidCastException("The type " + tType + " is not supported"); } else if (tType.IsClass && tType.GetConstructor(Type.EmptyTypes) == null) { throw new InvalidCastException("The type " + tType + " is missing a parameterless constructor"); } var columnMaps = odr.GetColumnMaps(tType, cmd?.MapSettings); if (tType.IsClass) { while (odr.Read()) { if (token.IsCancellationRequested) { return(projectedData); } projectedData.Add(odr.GetMappedObject <T>(columnMaps)); } } else { while (odr.Read()) { if (token.IsCancellationRequested) { return(projectedData); } projectedData.Add((T)odr.GetMappedObject(tType, columnMaps)); } } } } else if (tType == typeof(Dictionary <string, object>)) { projectedData = (List <T>)Convert.ChangeType(odr.ToDictionaries(false, token, cmd), typeof(List <Dictionary <string, object> >)); } else if (tType == typeof(List <KeyValuePair <string, object> >)) { projectedData = (List <T>)Convert.ChangeType(odr.ToKeyValuePairs(false, token, cmd), typeof(List <List <KeyValuePair <string, object> > >)); } else if (tType == typeof(DataTable)) { projectedData.Add((T)Convert.ChangeType(odr.ToDataTable(false, token, cmd.MapSettings), tType)); } else if (tType == typeof(DataSet)) { projectedData.Add((T)Convert.ChangeType(odr.ToDataSet(false, token, cmd.MapSettings), tType)); } else if (tType == typeof(object)) { projectedData = odr.ToList(token, cmd) as dynamic; } else { Type nonNullableObjType = tType.IsValueType ? (Nullable.GetUnderlyingType(tType) ?? tType) : tType; while (odr.Read()) { if (token.IsCancellationRequested) { return(projectedData); } object value = odr.GetValue(0); if (value != DBNull.Value) { projectedData.Add((T)(DbConnectorUtilities.ThrowIfFailedToMatchColumnType(tType, nonNullableObjType, value, () => odr.GetName(0)))); } else { projectedData.Add(default);
public static object GetMappedObject(this DbDataReader odr, Type objType, IColumnMapSetting settings = null) { var columnMaps = DbConnectorUtilities.GetColumnMaps(objType, odr.GetOrdinalColumnNames(settings), settings); return(odr.GetMappedObject(objType, columnMaps)); }
public static T GetMappedObject <T>(this DbDataReader odr, IColumnMapSetting settings = null) { var columnMaps = DbConnectorUtilities.GetColumnMaps(typeof(T), odr.GetOrdinalColumnNames(settings), settings); return(odr.GetMappedObject <T>(columnMaps)); }
/// <summary> /// Creates an <see cref="IEnumerable{ColumnMap}"/> based on the provided type. /// </summary> /// <param name="odr">The <see cref="DbDataReader"/> to use.</param> /// <param name="objType">The <see cref="Type"/> to use.</param> /// <param name="settings">The <see cref="IColumnMapSetting"/> to use. (Optional)</param> /// <returns>The <see cref="IEnumerable{ColumnMap}"/>.</returns> public static IEnumerable <ColumnMap> GetColumnMaps(this DbDataReader odr, Type objType, IColumnMapSetting settings = null) { return(DbConnectorUtilities.GetColumnMaps(objType, odr.GetOrdinalColumnNames(settings), settings)); }