Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do I Read A Rowversion or Timestamp SQL Server Data Type From a SQLDataReader to a C# Variable

I have a SQL Server 2012 database. Each table has a set of audit fields. One is a column named RowVer with a datatype of timestamp (same as rowversion).

I'm having difficulty reading the value from a SqlDataReader into a C# object with a property named User.RowVersion with a datatype of Byte[].

Code Snippet of while (rdr.Read()) block

...
user.DateCreated = rdr.GetDateTime(14);
user.CreatedByUserId = rdr.GetInt32(15);
if (!rdr.IsDBNull(16)) { user.DateLastUpdated = rdr.GetDateTime(16); }
if (!rdr.IsDBNull(17)) { user.LastUpdatedByUserId = rdr.GetInt32(17); }
user.RowVersion = rdr.???;
...

The RowVersion value is only used as a comparison for concurrency when updating the database.

This of course is NOT an EF implementation.

like image 320
Richard Avatar asked Oct 08 '15 00:10

Richard


2 Answers

If you are using .NET 4.5 or newer you can do

user.RowVersion = rdr.GetFieldValue<byte[]>(18);

If you are on 4.0 or older you will need to perform a cast.

user.RowVersion = rdr.GetValue(18) as byte[];
like image 128
Scott Chamberlain Avatar answered Sep 20 '22 02:09

Scott Chamberlain


One option is to handle this at the SQL level with the CONVERT() function, where it maps nicely to BIGINT:

CONVERT(BIGINT, MyRowVersionColumn)

And now you can read it easily into an Int64:

user.RowVersion = rdr.GetInt64(18);

That will, of course, mean changing the datatype of your object, but you may that this is a good thing.

If you want to keep the byte array, you can do this:

rdr.GetBytes(18, 0, user.RowVersion, 0, rdr.GetBytes());

Or, since the length of the field is known:

rdr.GetBytes(18, 0, user.RowVersion, 0, 8);   
like image 36
Joel Coehoorn Avatar answered Sep 18 '22 02:09

Joel Coehoorn