/// <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);
        }
示例#5
0
        /// <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));
 }