Working with the GridView and the System.Data.Linq.Binary Type
I'm working with a database table that has a RowVersion field defined as a TimeStamp data type. The TimeStamp field is there to add concurrency into the application to ensure a row hasn't changed while a user is trying to update or delete it. When the TimeStamp field value is queried and added into the LINQ to SQL generated object it adds it adds the data as a System.Data.Linq.Binary type as opposed to a byte array.
The GridView that is displaying records and allowing users to delete them defines the primary key in the DataKeyNames property as well as the RowVersion field so that the data is persisted across postback operations for each row. That's important because without the RowVersion value I can't update or delete a record and still take advantage of the concurrency features built-in to LINQ to SQL. The GridView definition looks like the following. Notice that two fields are defined in the DataKeyNames property which is par for the course if you're working with TimeStamp fields or multiple keys:
<asp:GridView ID="gvApprovedData" runat="server" BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px" CellPadding="6" ForeColor="Black" GridLines="Vertical" Width="50%" DataKeyNames="PrimaryKeyField,RowVersion" AutoGenerateColumns="False" onrowcommand="gvApprovedData_RowCommand">
....Columns.... </asp:GridView>
When I tried to get the serialized TimeStamp data back into the RowVersion property of the LINQ to SQL object (which is the Binary type I mentioned earlier) I kept getting a conversion error initially. I tried several different options such as the Convert class, converting character arrays to byte arrays, etc. but nothing worked at first. The main problem was that I was trying to convert the data held in key.Values[1] object to a String type and then convert that back to the Binary type. After playing around with it more I tried the super simple way of converting the data. I cast the serialized value directly to the Binary type which was much easier than I was expecting (see the code below). Very nice now that I know how it expects things to work!
protected void gvApprovedData_RowCommand(object sender, GridViewCommandEventArgs e) { int index = int.Parse(e.CommandArgument.ToString()); DataKey key = this.gvApprovedData.DataKeys[index]; BusinessObject bo = new BusinessObject(); CustomObject obj = new CustomObject { PrimaryKeyField = new Guid(key.Value.ToString()), RowVersion = (Binary)key.Values[1]}; OperationStatus opStatus = bo.DeleteRow(obj); if (opStatus.Status) { BindGrids(); } else { this.lblError.Text = "<br />An error occurred while trying to remove the row"; } }