@@ -14,7 +14,7 @@ namespace Microsoft.Data.SqlClient.Server
14
14
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/SqlDataRecord/*' />
15
15
public partial class SqlDataRecord : IDataRecord
16
16
{
17
- private readonly SmiRecordBuffer _recordBuffer ;
17
+ private readonly MemoryRecordBuffer _recordBuffer ;
18
18
private readonly SmiExtendedMetaData [ ] _columnSmiMetaData ;
19
19
private readonly SqlMetaData [ ] _columnMetaData ;
20
20
private FieldNameLookup _fieldNameLookup ;
@@ -54,10 +54,22 @@ public virtual string GetDataTypeName(int ordinal)
54
54
#if NET
55
55
[ return : DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes . PublicProperties | DynamicallyAccessedMemberTypes . PublicFields ) ]
56
56
#endif
57
- public virtual Type GetFieldType ( int ordinal ) => GetFieldTypeFrameworkSpecific ( ordinal ) ;
57
+ public virtual Type GetFieldType ( int ordinal )
58
+ {
59
+ SqlMetaData md = GetSqlMetaData ( ordinal ) ;
60
+
61
+ #if NETFRAMEWORK
62
+ if ( md . SqlDbType == SqlDbType . Udt )
63
+ {
64
+ return md . Type ;
65
+ }
66
+ #endif
67
+
68
+ return MetaType . GetMetaTypeFromSqlDbType ( md . SqlDbType , isMultiValued : false ) . ClassType ;
69
+ }
58
70
59
71
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetValue/*' />
60
- public virtual object GetValue ( int ordinal ) => GetValueFrameworkSpecific ( ordinal ) ;
72
+ public virtual object GetValue ( int ordinal ) => ValueUtilsSmi . GetValue200 ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) ) ;
61
73
62
74
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetValues/*' />
63
75
public virtual int GetValues ( object [ ] values )
@@ -177,7 +189,7 @@ public virtual SqlMetaData GetSqlMetaData(int ordinal)
177
189
public virtual Type GetSqlFieldType ( int ordinal ) => MetaType . GetMetaTypeFromSqlDbType ( GetSqlMetaData ( ordinal ) . SqlDbType , false ) . SqlType ;
178
190
179
191
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlValue/*' />
180
- public virtual object GetSqlValue ( int ordinal ) => GetSqlValueFrameworkSpecific ( ordinal ) ;
192
+ public virtual object GetSqlValue ( int ordinal ) => ValueUtilsSmi . GetSqlValue200 ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) ) ;
181
193
182
194
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlValues/*' />
183
195
public virtual int GetSqlValues ( object [ ] values )
@@ -200,10 +212,10 @@ public virtual int GetSqlValues(object[] values)
200
212
public virtual SqlBinary GetSqlBinary ( int ordinal ) => ValueUtilsSmi . GetSqlBinary ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) ) ;
201
213
202
214
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlBytes/*' />
203
- public virtual SqlBytes GetSqlBytes ( int ordinal ) => GetSqlBytesFrameworkSpecific ( ordinal ) ;
215
+ public virtual SqlBytes GetSqlBytes ( int ordinal ) => ValueUtilsSmi . GetSqlBytes ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) ) ;
204
216
205
217
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlXml/*' />
206
- public virtual SqlXml GetSqlXml ( int ordinal ) => GetSqlXmlFrameworkSpecific ( ordinal ) ;
218
+ public virtual SqlXml GetSqlXml ( int ordinal ) => ValueUtilsSmi . GetSqlXml ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) ) ;
207
219
208
220
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlBoolean/*' />
209
221
public virtual SqlBoolean GetSqlBoolean ( int ordinal ) => ValueUtilsSmi . GetSqlBoolean ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) ) ;
@@ -212,7 +224,7 @@ public virtual int GetSqlValues(object[] values)
212
224
public virtual SqlByte GetSqlByte ( int ordinal ) => ValueUtilsSmi . GetSqlByte ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) ) ;
213
225
214
226
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlChars/*' />
215
- public virtual SqlChars GetSqlChars ( int ordinal ) => GetSqlCharsFrameworkSpecific ( ordinal ) ;
227
+ public virtual SqlChars GetSqlChars ( int ordinal ) => ValueUtilsSmi . GetSqlChars ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) ) ;
216
228
217
229
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/GetSqlInt16/*' />
218
230
public virtual SqlInt16 GetSqlInt16 ( int ordinal ) => ValueUtilsSmi . GetSqlInt16 ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) ) ;
@@ -246,10 +258,78 @@ public virtual int GetSqlValues(object[] values)
246
258
247
259
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/SetValues/*' />
248
260
// ISqlUpdateableRecord Implementation
249
- public virtual int SetValues ( params object [ ] values ) => SetValuesFrameworkSpecific ( values ) ;
261
+ public virtual int SetValues ( params object [ ] values )
262
+ {
263
+ if ( values == null )
264
+ {
265
+ throw ADP . ArgumentNull ( nameof ( values ) ) ;
266
+ }
267
+
268
+ // Allow values array longer than FieldCount, just ignore the extra cells.
269
+ int copyLength = ( values . Length > FieldCount ) ? FieldCount : values . Length ;
270
+
271
+ if ( copyLength == 0 )
272
+ {
273
+ return 0 ;
274
+ }
275
+
276
+ ExtendedClrTypeCode [ ] typeCodes = new ExtendedClrTypeCode [ copyLength ] ;
277
+
278
+ // Verify all data values as acceptable before changing current state.
279
+ for ( int i = 0 ; i < copyLength ; i ++ )
280
+ {
281
+ SqlMetaData metaData = GetSqlMetaData ( i ) ;
282
+ typeCodes [ i ] = MetaDataUtilsSmi . DetermineExtendedTypeCodeForUseWithSqlDbType (
283
+ metaData . SqlDbType ,
284
+ isMultiValued : false ,
285
+ values [ i ] ,
286
+ metaData . Type ) ;
287
+ if ( typeCodes [ i ] == ExtendedClrTypeCode . Invalid )
288
+ {
289
+ throw ADP . InvalidCast ( ) ;
290
+ }
291
+ }
292
+
293
+ // Now move the data. We've already validated the element types above, so this will
294
+ // only throw if an invalid UDT was sent.
295
+ for ( int i = 0 ; i < copyLength ; i ++ )
296
+ {
297
+ ValueUtilsSmi . SetCompatibleValueV200 (
298
+ _recordBuffer ,
299
+ ordinal : i ,
300
+ GetSmiMetaData ( i ) ,
301
+ values [ i ] ,
302
+ typeCodes [ i ] ,
303
+ offset : 0 ,
304
+ peekAhead : null ) ;
305
+ }
306
+
307
+ return copyLength ;
308
+ }
250
309
251
310
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/SetValue/*' />
252
- public virtual void SetValue ( int ordinal , object value ) => SetValueFrameworkSpecific ( ordinal , value ) ;
311
+ public virtual void SetValue ( int ordinal , object value )
312
+ {
313
+ SqlMetaData metaData = GetSqlMetaData ( ordinal ) ;
314
+ ExtendedClrTypeCode typeCode = MetaDataUtilsSmi . DetermineExtendedTypeCodeForUseWithSqlDbType (
315
+ metaData . SqlDbType ,
316
+ isMultiValued : false ,
317
+ value ,
318
+ metaData . Type ) ;
319
+ if ( typeCode == ExtendedClrTypeCode . Invalid )
320
+ {
321
+ throw ADP . InvalidCast ( ) ;
322
+ }
323
+
324
+ ValueUtilsSmi . SetCompatibleValueV200 (
325
+ _recordBuffer ,
326
+ ordinal ,
327
+ GetSmiMetaData ( ordinal ) ,
328
+ value ,
329
+ typeCode ,
330
+ offset : 0 ,
331
+ peekAhead : null ) ;
332
+ }
253
333
254
334
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/SetBoolean/*' />
255
335
public virtual void SetBoolean ( int ordinal , bool value ) => ValueUtilsSmi . SetBoolean ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) , value ) ;
@@ -290,10 +370,10 @@ public virtual int GetSqlValues(object[] values)
290
370
public virtual void SetDateTime ( int ordinal , DateTime value ) => ValueUtilsSmi . SetDateTime ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) , value ) ;
291
371
292
372
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/SetTimeSpan/*' />
293
- public virtual void SetTimeSpan ( int ordinal , TimeSpan value ) => SetTimeSpanFrameworkSpecific ( ordinal , value ) ;
373
+ public virtual void SetTimeSpan ( int ordinal , TimeSpan value ) => ValueUtilsSmi . SetTimeSpan ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) , value ) ;
294
374
295
375
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/SetDateTimeOffset/*' />
296
- public virtual void SetDateTimeOffset ( int ordinal , DateTimeOffset value ) => SetDateTimeOffsetFrameworkSpecific ( ordinal , value ) ;
376
+ public virtual void SetDateTimeOffset ( int ordinal , DateTimeOffset value ) => ValueUtilsSmi . SetDateTimeOffset ( _recordBuffer , ordinal , GetSmiMetaData ( ordinal ) , value ) ;
297
377
298
378
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml' path='docs/members[@name="SqlDataRecord"]/SetDBNull/*' />
299
379
public virtual void SetDBNull ( int ordinal )
0 commit comments