88
99using System ;
1010using System . Collections . Generic ;
11- using System . Data . SqlClient ;
11+ using System . Data ;
12+ using System . Reflection ;
13+ using Devlord . Utilities . Resources ;
1214
1315namespace Devlord . Utilities
1416{
@@ -21,15 +23,17 @@ namespace Devlord.Utilities
2123 /// </remarks>
2224 public class DRMapper
2325 {
24- public static List < T > ParseList < T > ( SqlDataReader dr )
26+ public static List < T > ParseList < T > ( IDataReader dr )
2527 {
2628 var list = new List < T > ( ) ;
2729
2830 var properties = typeof ( T ) . GetProperties ( ) ;
29- var instance = Activator . CreateInstance < T > ( ) ;
31+
32+ VerifyTypeMatch < T > ( dr , properties ) ;
3033
3134 while ( dr . Read ( ) )
3235 {
36+ var instance = Activator . CreateInstance < T > ( ) ;
3337 foreach ( var pi in properties )
3438 {
3539 pi . SetValue ( instance , dr [ pi . Name ] , null ) ;
@@ -41,10 +45,41 @@ public static List<T> ParseList<T>(SqlDataReader dr)
4145 return list ;
4246 }
4347
44- public static T ParseRecord < T > ( SqlDataReader dr , int rowIndex = 0 )
48+ private static void VerifyTypeMatch < T > ( IDataRecord dr , IEnumerable < PropertyInfo > properties )
49+ {
50+ // Counter for when each field is found.
51+ var dictionary = new HashSet < string > ( StringComparer . CurrentCultureIgnoreCase ) ;
52+
53+ // Throw an error if the class expects columns that aren't being returned.
54+ foreach ( var pi in properties )
55+ {
56+ // Increment
57+ dictionary . Add ( pi . Name ) ;
58+ }
59+
60+ // Don't throw an error if the data set more verbose than the class we're filling
61+ for ( int i = 0 ; i < dr . FieldCount ; i ++ )
62+ {
63+ // Decrement.
64+ string column = dr . GetName ( i ) ;
65+ if ( dictionary . Contains ( column ) )
66+ {
67+ dictionary . Remove ( column ) ;
68+ }
69+ }
70+
71+ if ( dictionary . Count > 0 )
72+ {
73+ var ex = new Exception ( ExceptionText . DRMapperTypeTooComplex ) ;
74+ ex . Data . Add ( "Type" , typeof ( T ) ) ;
75+ ex . Data . Add ( "Missing fields" , string . Join ( ", " , dictionary ) ) ;
76+ throw ex ;
77+ }
78+ }
79+
80+ public static T ParseRecord < T > ( IDataReader dr , int rowIndex = 0 )
4581 {
4682 var properties = typeof ( T ) . GetProperties ( ) ;
47- var instance = Activator . CreateInstance < T > ( ) ;
4883
4984 var currentRow = 0 ;
5085 while ( dr . Read ( ) )
@@ -55,6 +90,7 @@ public static T ParseRecord<T>(SqlDataReader dr, int rowIndex = 0)
5590 continue ;
5691 }
5792
93+ var instance = Activator . CreateInstance < T > ( ) ;
5894 foreach ( var pi in properties )
5995 {
6096 pi . SetValue ( instance , dr [ pi . Name ] , null ) ;
@@ -63,6 +99,11 @@ public static T ParseRecord<T>(SqlDataReader dr, int rowIndex = 0)
6399 return instance ;
64100 }
65101
102+ if ( rowIndex > currentRow )
103+ {
104+ throw new IndexOutOfRangeException ( ExceptionText . DRMapperIndexOutOfRange ) ;
105+ }
106+
66107 return default ( T ) ;
67108 }
68109 }
0 commit comments