/// <summary>
        /// Gets one instance of <typeparamref name="T"/> from data reader.
        /// </summary>
        /// <typeparam name="T">Type of an instance.</typeparam>
        /// <param name="reader">Source data reader.</param>
        /// <param name="ctorParamMappings">Column constructor parameter mappings.</param>
        /// <param name="propMappings">Property column mappings.</param>
        /// <param name="breakAfterFirst">true to break after the first read record; false to not. if false throws exception if more than one record.</param>
        /// <returns>A single instance read from reader or null.</returns>
        private static T GetInstance <T>(DbDataReader reader, ColumnConstructorParameterMappingCollection <T> ctorParamMappings, IEnumerable <PropertyColumnMapping> propMappings, bool breakAfterFirst) where T : class
        {
            T instance = null;

            if (reader.HasRows)
            {
                //// create activator to create instance with constructor
                var activator = ActivatorFactory.GetActivator <T>(ctorParamMappings.Constructor);

                Dictionary <string, int> propertyColumnLookupTable = null;

                //// if contains property mappings, get lookup table
                if (propMappings != null)
                {
                    propertyColumnLookupTable = GetColumnIndexLookupTable(reader, propMappings.Select(x => x.ColumnName));
                }

                /// mappings between ctor params and columns
                var ctorColumnLookupTable = GetColumnIndexLookupTable(reader, ctorParamMappings.Select(x => x.ColumnName));

                bool first = true;

                while (reader.Read())
                {
                    if (!first)
                    {
                        throw new InvalidOperationException("Reader contains more than expected 1 record.");
                    }

                    object[] arguments = null;

                    //// get constructor arguments
                    if (ctorParamMappings.HasParameters)
                    {
                        arguments = GetConstructorParameters(reader, ctorColumnLookupTable, ctorParamMappings);
                    }

                    //// create instance
                    instance = activator.Invoke(arguments);

                    //// if contains property mappings, read values
                    if (propMappings != null)
                    {
                        ReadData(instance, reader, propMappings, propertyColumnLookupTable);
                    }

                    if (breakAfterFirst)
                    {
                        break;
                    }

                    first = false;
                }
            }

            return(instance);
        }
        /// <summary>
        /// Gets all instances from data reader.
        /// </summary>
        /// <typeparam name="T">Type of an object read.</typeparam>
        /// <param name="reader">The source <see cref="DbDataReader"/> instance.</param>
        /// <param name="ctorMappings">The mappings between constructor arguments and columns.</param>
        /// <param name="propMappings">The mappings between properties and columns.</param>
        /// <returns>A enumerable of <typeparamref name="T"/> instances.</returns>
        public static IEnumerable <T> GetRecords <T>(this DbDataReader reader, ColumnConstructorParameterMappingCollection <T> ctorMappings, IEnumerable <PropertyColumnMapping> propMappings) where T : class
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            if (ctorMappings == null)
            {
                throw new ArgumentNullException("ctorMappings");
            }

            var result = new List <T>();

            if (reader.HasRows)
            {
                var activator = ActivatorFactory.GetActivator <T>(ctorMappings.Constructor);

                Dictionary <string, int> propertyColumnLookupTable = null;

                //// if contains property mappings, get lookup table
                if (propMappings != null)
                {
                    propertyColumnLookupTable = GetColumnIndexLookupTable(reader, propMappings.Select(x => x.ColumnName));
                }

                /// mappings between ctor params and columns
                var ctorColumnLookupTable = GetColumnIndexLookupTable(reader, ctorMappings.Select(x => x.ColumnName));

                while (reader.Read())
                {
                    object[] arguments = null;

                    //// get constructor arguments
                    if (ctorMappings.HasParameters)
                    {
                        arguments = GetConstructorParameters(reader, ctorColumnLookupTable, ctorMappings);
                    }

                    var instance = activator.Invoke(arguments);

                    //// if contains property mappings, read values
                    if (propMappings != null)
                    {
                        ReadData(instance, reader, propMappings, propertyColumnLookupTable);
                    }

                    result.Add(instance);
                }
            }

            return(result);
        }
        /// <summary>
        /// Gets first instance from data reader.
        /// </summary>
        /// <typeparam name="T">Type of an object read.</typeparam>
        /// <param name="reader">The source <see cref="DbDataReader"/> instance.</param>
        /// <param name="ctorMappings">The mappings between constructor arguments and columns.</param>
        /// <param name="propMappings">The mappings between properties and columns.</param>
        /// <returns>A first <typeparamref name="T"/> instance or default <typeparamref name="T"/>.</returns>
        public static T GetFirstRecord <T>(this DbDataReader reader, ColumnConstructorParameterMappingCollection <T> ctorMappings, IEnumerable <PropertyColumnMapping> propMappings = null) where T : class
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            if (ctorMappings == null)
            {
                throw new ArgumentNullException("ctorMappings");
            }

            return(GetInstance <T>(reader, ctorMappings, propMappings, true));
        }
        /// <summary>
        /// Gets the object array of constructor arguments.
        /// </summary>
        /// <typeparam name="T">Type of an instance.</typeparam>
        /// <param name="reader">Source data reader.</param>
        /// <param name="lookupTable">Column name column ordinal lookup table.</param>
        /// <param name="ctorMappings">Column constructor parameter mappings.</param>
        /// <returns>Object array of constructor parameters.</returns>
        private static object[] GetConstructorParameters <T>(DbDataReader reader, Dictionary <string, int> lookupTable, ColumnConstructorParameterMappingCollection <T> ctorMappings) where T : class
        {
            object[] args = new object[ctorMappings.Count];

            foreach (var mapping in ctorMappings)
            {
                int ordinal = lookupTable[mapping.ColumnName];

                //// read value
                object value = GetValue(reader, mapping.CanBeNull, ordinal, mapping.ColumnName);

                //// if mappings does not accept nulls, but null was read
                //// throw exception
                if (!mapping.CanBeNull && value == null)
                {
                    throw new NullReferenceException(String.Format("Constructor parameter does not accept null references, but null was read from column {0}.", mapping.ColumnName));
                }

                //// if value is not null, perform value check
                if (value != null)
                {
                    value = CheckValue(value, mapping.ConstructorParameterType);
                }

                //// store to arguments array
                args[mapping.ConstructorParameterIndex] = value;
            }

            return(args);
        }