@@ -40,34 +40,57 @@ public class SpannerDataReader : DbDataReader
4040 private bool _closed ;
4141 private bool _hasReadData ;
4242 private bool _hasData ;
43+
44+ private ResultSetMetadata ? _metadata ;
45+
46+ private ResultSetMetadata ? Metadata
47+ {
48+ get
49+ {
50+ if ( _metadata == null )
51+ {
52+ CheckNotClosed ( ) ;
53+ _metadata = LibRows . Metadata ;
54+ }
55+ return _metadata ;
56+ }
57+ }
4358
4459 public override int FieldCount
4560 {
4661 get
4762 {
4863 CheckNotClosed ( ) ;
49- return LibRows . Metadata ? . RowType . Fields . Count ?? 0 ;
64+ return Metadata ? . RowType . Fields . Count ?? 0 ;
5065 }
5166 }
5267
5368 public override object this [ int ordinal ] => GetFieldValue < object > ( ordinal ) ;
5469 public override object this [ string name ] => this [ GetOrdinal ( name ) ] ;
5570
56- public override int RecordsAffected
71+ private long ? _stats ;
72+
73+ private long ? Stats
5774 {
5875 get
5976 {
60- CheckNotClosed ( ) ;
61- return ( int ) LibRows . UpdateCount ;
77+ if ( _stats == null )
78+ {
79+ CheckNotClosed ( ) ;
80+ _stats = LibRows . UpdateCount ;
81+ }
82+ return _stats ;
6283 }
6384 }
6485
86+ public override int RecordsAffected => ( int ) ( Stats ?? 0 ) ;
87+
6588 public override bool HasRows
6689 {
6790 get
6891 {
6992 CheckNotClosed ( ) ;
70- if ( LibRows . Metadata ? . RowType . Fields . Count == 0 )
93+ if ( Metadata ? . RowType . Fields . Count == 0 )
7194 {
7295 return false ;
7396 }
@@ -167,7 +190,7 @@ private bool CheckForRows()
167190 public override DataTable ? GetSchemaTable ( )
168191 {
169192 CheckNotClosed ( ) ;
170- var metadata = LibRows . Metadata ;
193+ var metadata = Metadata ;
171194 if ( metadata ? . RowType == null || metadata . RowType . Fields . Count == 0 )
172195 {
173196 return null ;
@@ -293,7 +316,7 @@ public override long GetBytes(int ordinal, long dataOffset, byte[]? buffer, int
293316 CheckValidPosition ( ) ;
294317 CheckValidOrdinal ( ordinal ) ;
295318 CheckNotNull ( ordinal ) ;
296- var code = LibRows . Metadata ! . RowType . Fields [ ordinal ] . Type . Code ;
319+ var code = Metadata ! . RowType . Fields [ ordinal ] . Type . Code ;
297320 GaxPreconditions . CheckState ( Array . Exists ( [ TypeCode . Bytes , TypeCode . Json , TypeCode . String ] , c => c == code ) ,
298321 "Spanner only supports conversion to byte arrays for columns of type BYTES or STRING." ) ;
299322 Preconditions . CheckIndexRange ( bufferOffset , nameof ( bufferOffset ) , 0 , buffer ? . Length ?? 0 ) ;
@@ -400,7 +423,7 @@ public override long GetChars(int ordinal, long dataOffset, char[]? buffer, int
400423 public override string GetDataTypeName ( int ordinal )
401424 {
402425 CheckValidOrdinal ( ordinal ) ;
403- return GetTypeName ( LibRows . Metadata ! . RowType . Fields [ ordinal ] . Type ) ;
426+ return GetTypeName ( Metadata ! . RowType . Fields [ ordinal ] . Type ) ;
404427 }
405428
406429 private static string GetTypeName ( Google . Cloud . Spanner . V1 . Type type )
@@ -481,7 +504,7 @@ public override double GetDouble(int ordinal)
481504 public override System . Type GetFieldType ( int ordinal )
482505 {
483506 CheckValidOrdinal ( ordinal ) ;
484- return GetClrType ( LibRows . Metadata ! . RowType . Fields [ ordinal ] . Type ) ;
507+ return GetClrType ( Metadata ! . RowType . Fields [ ordinal ] . Type ) ;
485508 }
486509
487510 private static System . Type GetClrType ( Google . Cloud . Spanner . V1 . Type type )
@@ -635,24 +658,24 @@ public override long GetInt64(int ordinal)
635658 public override string GetName ( int ordinal )
636659 {
637660 CheckValidOrdinal ( ordinal ) ;
638- return LibRows . Metadata ! . RowType . Fields [ ordinal ] . Name ;
661+ return Metadata ! . RowType . Fields [ ordinal ] . Name ;
639662 }
640663
641664 public override int GetOrdinal ( string name )
642665 {
643666 CheckNotClosed ( ) ;
644667 // First try with case sensitivity.
645- for ( var i = 0 ; i < LibRows . Metadata ? . RowType . Fields . Count ; i ++ )
668+ for ( var i = 0 ; i < Metadata ? . RowType . Fields . Count ; i ++ )
646669 {
647- if ( Equals ( LibRows . Metadata ? . RowType . Fields [ i ] . Name , name ) )
670+ if ( Equals ( Metadata ? . RowType . Fields [ i ] . Name , name ) )
648671 {
649672 return i ;
650673 }
651674 }
652675 // Nothing found, try with case-insensitive comparison.
653- for ( var i = 0 ; i < LibRows . Metadata ? . RowType . Fields . Count ; i ++ )
676+ for ( var i = 0 ; i < Metadata ? . RowType . Fields . Count ; i ++ )
654677 {
655- if ( string . Equals ( LibRows . Metadata ? . RowType . Fields [ i ] . Name , name , StringComparison . InvariantCultureIgnoreCase ) )
678+ if ( string . Equals ( Metadata ? . RowType . Fields [ i ] . Name , name , StringComparison . InvariantCultureIgnoreCase ) )
656679 {
657680 return i ;
658681 }
@@ -739,7 +762,7 @@ public override object GetValue(int ordinal)
739762 {
740763 CheckValidOrdinal ( ordinal ) ;
741764 CheckValidPosition ( ) ;
742- var type = LibRows . Metadata ! . RowType . Fields [ ordinal ] . Type ;
765+ var type = Metadata ! . RowType . Fields [ ordinal ] . Type ;
743766 var value = _currentRow ! . Values [ ordinal ] ;
744767 return GetUnderlyingValue ( type , value ) ;
745768 }
@@ -815,7 +838,7 @@ private Value GetProtoValue(int ordinal)
815838 private V1 . Type GetSpannerType ( int ordinal )
816839 {
817840 CheckValidOrdinal ( ordinal ) ;
818- return LibRows . Metadata ? . RowType . Fields [ ordinal ] . Type ?? throw new DataException ( "metadata not found" ) ;
841+ return Metadata ? . RowType . Fields [ ordinal ] . Type ?? throw new DataException ( "metadata not found" ) ;
819842 }
820843
821844 public override int GetValues ( object [ ] values )
@@ -862,7 +885,7 @@ private void CheckValidPosition()
862885 private void CheckValidOrdinal ( int ordinal )
863886 {
864887 CheckNotClosed ( ) ;
865- var metadata = LibRows . Metadata ;
888+ var metadata = Metadata ;
866889 GaxPreconditions . CheckState ( metadata != null && metadata . RowType . Fields . Count > 0 , "This reader does not contain any rows" ) ;
867890
868891 // Check that the ordinal is within the range of the columns in the query.
0 commit comments