none
Storing rowversion value in string variable RRS feed

  • Question

  • Hi All,

    I am having a situation in a project where I am transferring data over WCF service to the windows client application. I have written a wrapper class which is available on both sides (service and client). When service returns the data to the client in the form of datatable, this class first converts datatable into string array as follows:

    1. It stores each row values in the string separated by chr(2) and then add this string variable to the array.
    2. First value of array contains the datatypes of the columns of the datatable separated by chr(2)
    3. Second value of array contains the column names of the datatable

    This string array is returned to the client and the same class reverse the string array back into datatable. This works perfectly fine. But when datatable at the server side contains rowversion column, it stores string "System.Byte" in the string variable and I get an error "Type mismatch" at the client side while building the datatable from the string array.

    Can someone help me how to pass this rowversion value through this string array to the client side?

    Regards,

    Prabi


    I can be still better.
    Thursday, January 6, 2011 9:50 AM

Answers

  •  I have also tried GetXml method of Dataset but it fails if no. of records are large.

    Wow, really? I've never had a problem using GetXml and have had some fairly large DataSets. How many records are you passing? What kind of error do you get?

    I really only mentioned the .GetXml() solution because you were trying to pass DataTable info & the DataSet.GetXml() nicely serializes the data into an XML string. However, you really should use something more standard since you're using WCF. Serialization is the best way to go ... take a look at either XmlSerialization or DataContractSerialization.

    http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx
    http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx

    But, if you'd like to stay with your current implementation, and just fix the problem you're having, let's take a look at the code you're using to put the data into the arrays on the server side. You need to do something different for the rowversion data, and it would help to see what you're currently doing.


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Monday, January 10, 2011 5:37 PM
  • Your rowversion column is a byte array, byte[8] ... the .ToString() method returns "System.Byte[]", as you saw. You're going to have to handle this datatype differently, both converting to/from. Do this whenever the DataType in the column is System.Byte[]. 

    I don't have any sample code at the moment, but you're going to have to parse each of the 8 bytes individually to a string, and then back the other way for the reverse. You can play with this yourself as well as I can, so I'll let you figure out the rest. If you get stuck, let me know and I can play with it myself (don't have time right this minute).


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Wednesday, January 12, 2011 5:00 PM

All replies

  • I suggest passing XML strings instead.

    // server-side returns this:
    return MyDataSet.GetXml();
    

     

    // client-side takes the XML string, reads it back into the DataSet
    StringReader sr = new StringReader(XML);
    ds.ReadXml(sr, XmlReadMode.InferSchema);
    ds.AcceptChanges();
    
    

    See if that solves your problem.


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Saturday, January 8, 2011 5:58 PM
  • Hi Bonnie,

    Thanks for your reply.

    I am converting datatable into string array. Datatable doesn't have GetXml method. I have also tried GetXml method of Dataset but it fails if no. of records are large. I have to find some solution for handling rowversion column in string array.

    Regards,

    Prabi


    I can be still better.
    Monday, January 10, 2011 8:37 AM
  •  I have also tried GetXml method of Dataset but it fails if no. of records are large.

    Wow, really? I've never had a problem using GetXml and have had some fairly large DataSets. How many records are you passing? What kind of error do you get?

    I really only mentioned the .GetXml() solution because you were trying to pass DataTable info & the DataSet.GetXml() nicely serializes the data into an XML string. However, you really should use something more standard since you're using WCF. Serialization is the best way to go ... take a look at either XmlSerialization or DataContractSerialization.

    http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx
    http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx

    But, if you'd like to stay with your current implementation, and just fix the problem you're having, let's take a look at the code you're using to put the data into the arrays on the server side. You need to do something different for the rowversion data, and it would help to see what you're currently doing.


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Monday, January 10, 2011 5:37 PM
  • Hi Bonnie,

    I would like to stay with my current implementation. Please see the class which is available on both server and client side in order to convert DT to string array and back to DT.

    Public Class DataWrapper
    
    Public Function GetArrayFromDataTable(ByVal dtData As DataTable) As String()
        'Array is declared
        Dim arrData(dtData.Rows.Count + 1) As String
    
        'Loop variables
        Dim sRowValue As String = ""
        Dim sColName As String = ""
        Dim iRowIndex As Integer = 2
    
        'Looping through all datacolumns and forming a string of their datatypes as well as column names seperated by chr(2)
        For Each dc As DataColumn In dtData.Columns
          If sRowValue = "" Then
            sRowValue = dc.DataType.ToString
            sColName = dc.ColumnName
          Else
            sRowValue = String.Concat(sRowValue, ColumnSeperator, dc.DataType.ToString)
            sColName = String.Concat(sColName, ColumnSeperator, dc.ColumnName)
          End If
        Next
    
        'storing string of datatypes in the first element of the array
        arrData(0) = sRowValue
        'storing string of column name in the second element of the array.
        arrData(1) = sColName
        sRowValue = ""
        sColName = ""
    
        'Looping through all rows to form a string of data for each row
        For Each dr As DataRow In dtData.Rows
          'Looping through all datacolumns to form a string of particular datarow seperated by constant declared at the class level
          For Each dc As DataColumn In dtData.Columns
            If sRowValue = "" Then
              sRowValue = IIf(dr(dc.ColumnName) Is DBNull.Value, NULLValue, dr(dc.ColumnName))
            Else
              sRowValue = String.Concat(sRowValue, ColumnSeperator, IIf(dr(dc.ColumnName) Is DBNull.Value, NULLValue, dr(dc.ColumnName)))
            End If
          Next
          'Storing this string in the array
          arrData(iRowIndex) = sRowValue
          'Incementing row index
          iRowIndex = iRowIndex + 1
          'setting the string variable to blank string again
          sRowValue = ""
        Next
    
        'Finally returing the array
        Return arrData
    End Function
    
    Public Function GetDataTableFromArray(ByVal sData() As String) As DataTable
        'Declaring new datatable
        Dim dtData As New DataTable
    
        'Looping through all elements to convert strings into datarows
        For iIndex As Integer = 0 To sData.Length - 1
          'spliting the string and storing it into string array
          Dim sOneRow() As Object = Split(sData(iIndex), ColumnSeperator)
          'If rowindex is zero then create columns for the datatable using the information for datatypes and column names
          If iIndex = 0 Then
            For Each sOneValue As String In sOneRow
              Dim dc As New DataColumn("", Type.GetType(sOneValue))
              'Adding datacolumn to the table's column collection
              dtData.Columns.Add(dc)
            Next
    
            Dim sColNames As String() = Split(sData(iIndex + 1), ColumnSeperator)
            Dim nColNameIndex As Integer = 0
            For Each col As DataColumn In dtData.Columns
              col.ColumnName = sColNames(nColNameIndex)
              nColNameIndex = nColNameIndex + 1
            Next
            sColNames = Nothing
            'Incrementing index by one because array index 1 is already used while creating column. so now we have
            'go to next index to get the actual data
            iIndex = iIndex + 1
          Else
            'creating new datarow
            'Dim dr As DataRow
            'dr = dtData.NewRow
            For iElem As Integer = 0 To sOneRow.Length - 1
              If sOneRow(iElem) = NULLValue Then sOneRow(iElem) = Nothing
            Next
    
            dtData.LoadDataRow(sOneRow, True)
            Dim iColIndex As Integer = 0
            'Looping through all elements of spitted string array to add values to created datarow.
            'For Each sOneValue As String In sOneRow
            '  'make sure that if value is NullValue constant(declared at the class level) then add System.DBNull.Value to the table
            '  dr(iColIndex) = IIf(sOneValue = NULLValue, DBNull.Value, sOneValue)
            '  'Incrementing column index by 1
            '  iColIndex = iColIndex + 1
            'Next
            'Adding the row having values to the datatable
            'dtData.Rows.Add(dr)
          End If
          sOneRow = Nothing
        Next
        sData = Nothing
        'Finally returning the populated datatable
        Return dtData
    End Function
    
    End Class
    

    Regards,

    Prabi


    I can be still better.
    Wednesday, January 12, 2011 5:00 AM
  • Your rowversion column is a byte array, byte[8] ... the .ToString() method returns "System.Byte[]", as you saw. You're going to have to handle this datatype differently, both converting to/from. Do this whenever the DataType in the column is System.Byte[]. 

    I don't have any sample code at the moment, but you're going to have to parse each of the 8 bytes individually to a string, and then back the other way for the reverse. You can play with this yourself as well as I can, so I'll let you figure out the rest. If you get stuck, let me know and I can play with it myself (don't have time right this minute).


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Wednesday, January 12, 2011 5:00 PM