private static ColumnInfo[] ReflectRow(Type type, IDataRecord reader) { var properties = type.GetProperties(); Type[] columnTypes = type.GetGenericArguments(); Loader.ColumnInfo[] columns; string propertyName = Text.NotAvailable; int columnCount = columnTypes.Length; if (reader.FieldCount < columnTypes.Length) { throw new QueryTalkException("Loader.ReflectRow", QueryTalkExceptionType.NoMoreColumns, String.Format("QtRow = {0}{1} Number of columns in data source = {2}", type, Environment.NewLine, reader.FieldCount)); } try { QueryTalkException exception; columns = new Loader.ColumnInfo[columnCount]; for (int i = 0; i < columnCount; ++i) { Type columnType = columnTypes[i]; Loader.ColumnInfo column = new Loader.ColumnInfo(); PropertyInfo property = properties[i]; propertyName = property.Name; Type clrType; if (Mapping.CheckClrCompliance(columnType, out clrType, out exception) != Mapping.ClrTypeMatch.ClrMatch) { exception.Arguments = String.Format("class = {0}{1} property = {2}{3} {4}", type, Environment.NewLine, property.Name, Environment.NewLine, exception.Arguments); throw exception; } ClrMappingInfo mapping; if (columnType.IsNullable()) { column.IsNullable = true; column.ValueType = Nullable.GetUnderlyingType(columnType); mapping = Mapping.ClrMapping[column.ValueType]; } else { column.IsNullable = false; column.ValueType = columnType; mapping = Mapping.ClrMapping[columnType]; } column.ReaderGetMethod = typeof(SqlDataReader).GetMethod(mapping.SqlDataReaderGetMethodName, new Type[] { typeof(int) }); column.ReaderOrdinal = i; column.Property = property; column.IsUnbox = mapping.IsUnbox; column.CtorParameterType = mapping.CtorParameterType; column.ColumnName = property.Name; columns[i] = column; } return(columns); } catch (System.IndexOutOfRangeException) // property name does not match any IDataReader field { throw new QueryTalkException("Reader.ReflectRow", QueryTalkExceptionType.MismatchedTargetColumn, String.Format("class = {0}{1} property = {2}", type, Environment.NewLine, propertyName)); } }
private static ColumnInfo[] ReflectClass(Type type, IDataRecord reader) { string propertyName = Text.NotAvailable; CheckParmeterlessConstructorAndThrow(type); PropertyInfo[] properties = type.GetWritableProperties(); if (properties.Length == 0) { throw new QueryTalkException("Reader.ReflectClass<T>", QueryTalkExceptionType.InvalidDataClass, String.Format("data class = {0}", type)); } var schema = ((SqlDataReader)reader).GetSchemaTable(); var clrNames = schema.AsEnumerable() .Select(a => Naming.GetClrName(a.Field <string>(_columnNameText))) .ToList(); IEnumerable <string> duplicates; Common.FindDuplicates(clrNames, out duplicates); QueryTalkException exception; var columns = new List <Loader.ColumnInfo>(); int i = 0; foreach (PropertyInfo property in properties) { propertyName = property.Name; Loader.ColumnInfo column = new Loader.ColumnInfo(); Type clrType; var clrTypeMatch = Mapping.CheckClrCompliance(property.PropertyType, out clrType, out exception); if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch) { continue; } ClrMappingInfo mapping; if (property.PropertyType.IsNullable()) { column.IsNullable = true; column.ValueType = Nullable.GetUnderlyingType(property.PropertyType); mapping = Mapping.ClrMapping[column.ValueType]; } else { column.IsNullable = false; column.ValueType = property.PropertyType; mapping = Mapping.ClrMapping[property.PropertyType]; } var match = schema.AsEnumerable() .Where(a => Naming.GetClrName(a.Field <string>(_columnNameText)).EqualsCS(property.Name)) .FirstOrDefault(); // allow column mismatch - ! if (match == null) { continue; } if (duplicates.Contains(match.Field <string>(_columnNameText))) { throw new QueryTalkException("Loader.ReflectReader", QueryTalkExceptionType.ColumnNameDuplicate, String.Format("duplicate CLR name(s) = {0}", match.Field <string>(_columnNameText))); } int ordinal = match.Field <int>(_columnOrdinalText); column.ReaderGetMethod = typeof(SqlDataReader).GetMethod(mapping.SqlDataReaderGetMethodName, new Type[] { typeof(int) }); column.ReaderOrdinal = ordinal; column.Property = property; column.IsUnbox = mapping.IsUnbox; column.CtorParameterType = mapping.CtorParameterType; column.ColumnName = property.Name; columns.Add(column); ++i; } return(columns.ToArray()); }