11using System ;
22using System . Collections . Generic ;
33using System . Data ;
4+ using System . Data . Common ;
45
56namespace Dapper
67{
@@ -13,14 +14,15 @@ public static partial class SqlMapper
1314 /// <param name="reader">The data reader to parse results from.</param>
1415 public static IEnumerable < T > Parse < T > ( this IDataReader reader )
1516 {
16- if ( reader . Read ( ) )
17+ var dbReader = GetDbDataReader ( reader , false ) ;
18+ if ( dbReader . Read ( ) )
1719 {
1820 var effectiveType = typeof ( T ) ;
19- var deser = GetDeserializer ( effectiveType , reader , 0 , - 1 , false ) ;
21+ var deser = GetDeserializer ( effectiveType , dbReader , 0 , - 1 , false ) ;
2022 var convertToType = Nullable . GetUnderlyingType ( effectiveType ) ?? effectiveType ;
2123 do
2224 {
23- object val = deser ( reader ) ;
25+ object val = deser ( dbReader ) ;
2426 if ( val == null || val is T )
2527 {
2628 yield return ( T ) val ;
@@ -29,7 +31,7 @@ public static IEnumerable<T> Parse<T>(this IDataReader reader)
2931 {
3032 yield return ( T ) Convert . ChangeType ( val , convertToType , System . Globalization . CultureInfo . InvariantCulture ) ;
3133 }
32- } while ( reader . Read ( ) ) ;
34+ } while ( dbReader . Read ( ) ) ;
3335 }
3436 }
3537
@@ -40,13 +42,14 @@ public static IEnumerable<T> Parse<T>(this IDataReader reader)
4042 /// <param name="type">The type to parse from the <paramref name="reader"/>.</param>
4143 public static IEnumerable < object > Parse ( this IDataReader reader , Type type )
4244 {
43- if ( reader . Read ( ) )
45+ var dbReader = GetDbDataReader ( reader , false ) ;
46+ if ( dbReader . Read ( ) )
4447 {
45- var deser = GetDeserializer ( type , reader , 0 , - 1 , false ) ;
48+ var deser = GetDeserializer ( type , dbReader , 0 , - 1 , false ) ;
4649 do
4750 {
48- yield return deser ( reader ) ;
49- } while ( reader . Read ( ) ) ;
51+ yield return deser ( dbReader ) ;
52+ } while ( dbReader . Read ( ) ) ;
5053 }
5154 }
5255
@@ -56,13 +59,14 @@ public static IEnumerable<object> Parse(this IDataReader reader, Type type)
5659 /// <param name="reader">The data reader to parse results from.</param>
5760 public static IEnumerable < dynamic > Parse ( this IDataReader reader )
5861 {
59- if ( reader . Read ( ) )
62+ var dbReader = GetDbDataReader ( reader , false ) ;
63+ if ( dbReader . Read ( ) )
6064 {
61- var deser = GetDapperRowDeserializer ( reader , 0 , - 1 , false ) ;
65+ var deser = GetDapperRowDeserializer ( dbReader , 0 , - 1 , false ) ;
6266 do
6367 {
64- yield return deser ( reader ) ;
65- } while ( reader . Read ( ) ) ;
68+ yield return deser ( dbReader ) ;
69+ } while ( dbReader . Read ( ) ) ;
6670 }
6771 }
6872
@@ -76,12 +80,47 @@ public static IEnumerable<dynamic> Parse(this IDataReader reader)
7680 /// <param name="length">The length of columns to read (default -1 = all fields following startIndex)</param>
7781 /// <param name="returnNullIfFirstMissing">Return null if we can't find the first column? (default false)</param>
7882 /// <returns>A parser for this specific object from this row.</returns>
83+ #if DEBUG // make sure we're not using this internally
84+ [ Obsolete ( nameof ( DbDataReader ) + " API should be preferred" ) ]
85+ #endif
7986 public static Func < IDataReader , object > GetRowParser ( this IDataReader reader , Type type ,
8087 int startIndex = 0 , int length = - 1 , bool returnNullIfFirstMissing = false )
88+ {
89+ return WrapObjectReader ( GetDeserializer ( type , GetDbDataReader ( reader , false ) , startIndex , length , returnNullIfFirstMissing ) ) ;
90+ }
91+
92+ /// <summary>
93+ /// Gets the row parser for a specific row on a data reader. This allows for type switching every row based on, for example, a TypeId column.
94+ /// You could return a collection of the base type but have each more specific.
95+ /// </summary>
96+ /// <param name="reader">The data reader to get the parser for the current row from</param>
97+ /// <param name="type">The type to get the parser for</param>
98+ /// <param name="startIndex">The start column index of the object (default 0)</param>
99+ /// <param name="length">The length of columns to read (default -1 = all fields following startIndex)</param>
100+ /// <param name="returnNullIfFirstMissing">Return null if we can't find the first column? (default false)</param>
101+ /// <returns>A parser for this specific object from this row.</returns>
102+ public static Func < DbDataReader , object > GetRowParser ( this DbDataReader reader , Type type ,
103+ int startIndex = 0 , int length = - 1 , bool returnNullIfFirstMissing = false )
81104 {
82105 return GetDeserializer ( type , reader , startIndex , length , returnNullIfFirstMissing ) ;
83106 }
84107
108+ /// <inheritdoc cref="GetRowParser{T}(DbDataReader, Type, int, int, bool)"/>
109+ #if DEBUG // make sure we're not using this internally
110+ [ Obsolete ( nameof ( DbDataReader ) + " API should be preferred" ) ]
111+ #endif
112+ public static Func < IDataReader , T > GetRowParser < T > ( this IDataReader reader , Type concreteType = null ,
113+ int startIndex = 0 , int length = - 1 , bool returnNullIfFirstMissing = false )
114+ {
115+ concreteType ??= typeof ( T ) ;
116+ var func = GetDeserializer ( concreteType , GetDbDataReader ( reader , false ) , startIndex , length , returnNullIfFirstMissing ) ;
117+ return Wrap ( func ) ;
118+
119+ // this is just to be very clear about what we're capturing
120+ static Func < IDataReader , T > Wrap ( Func < DbDataReader , object > func )
121+ => reader => ( T ) func ( GetDbDataReader ( reader , false ) ) ;
122+ }
123+
85124 /// <summary>
86125 /// Gets the row parser for a specific row on a data reader. This allows for type switching every row based on, for example, a TypeId column.
87126 /// You could return a collection of the base type but have each more specific.
@@ -135,7 +174,7 @@ public static Func<IDataReader, object> GetRowParser(this IDataReader reader, Ty
135174 /// public override int Type => 2;
136175 /// }
137176 /// </example>
138- public static Func < IDataReader , T > GetRowParser < T > ( this IDataReader reader , Type concreteType = null ,
177+ public static Func < DbDataReader , T > GetRowParser < T > ( this DbDataReader reader , Type concreteType = null ,
139178 int startIndex = 0 , int length = - 1 , bool returnNullIfFirstMissing = false )
140179 {
141180 concreteType ??= typeof ( T ) ;
@@ -146,7 +185,7 @@ public static Func<IDataReader, T> GetRowParser<T>(this IDataReader reader, Type
146185 }
147186 else
148187 {
149- return ( Func < IDataReader , T > ) ( Delegate ) func ;
188+ return ( Func < DbDataReader , T > ) ( Delegate ) func ;
150189 }
151190 }
152191 }
0 commit comments