Serializing and DeSerializing a TypedView

Posts   
 
    
mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 08-Jul-2006 20:42:09   

All--

Please help.

I am having fun Serializing and DeSerializing a TypedView.

I ask...

(1) Does anyone have a code sample to share?

(2) Which serializer should one use?

That is, which of the following should one use...

...System.Runtime.Serialization.Formatters.Soap... ...OR... ...System.Xml.Serialization.XmlSerializer... ...OR... ...it does not matter... ...OR... ...something else?

(3) What encoding should one use?

That is, when one is using System.Runtime.Serialization.Formatters.Soap, the serialization produces an Array of Bytes, Byte(). To get this into a String, one needs to know the encoding; but, which encoding to use is not obvious. What is the correrct encoding to use in the code sample below?


'option1... might work...
Dim myEncoding As System.Text.ASCIIEncoding = New System.Text.ASCIIEncoding

'option2... does not work...
'Dim myEncoding As System.Text.UnicodeEncoding = New System.Text.UnicodeEncoding

'option3... might work... 
'Dim myEncoding As System.Text.UTF7Encoding = New System.Text.UTF7Encoding

'option4... might work... 
'Dim myEncoding As System.Text.UTF8Encoding = New System.Text.UTF8Encoding

Dim myByteArray As Byte() = myMemoryStream.ToArray()
myXml = myEncoding.GetString(myByteArray)

Any help is appreciated.

Suggestion for future enhancement... ...add ReadXml() and WriteXml() methods to the TypedView, to make things easy to use and to make things uniform with Entity and EntityCollection APIs.

BTW, we are using... ...the latest-and-greatest LLBLGen release version as posted at http://www.LLBLGen.com and we are using VS.NET 2003 and we have both WindowsForms and WebForms clients.)

Thank you.

-- Mark Kamoski

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 10-Jul-2006 11:44:15   

TypedView's are datatables.

so if you want them in XML, in .NET 1.x, add them to a dataset and serialize the dataset with writexml. If you're in .NET 2.0, you can use the WriteXml method on the datatable, which is the base class of the typedview class.

Binary serialization is supported as well, simply use the binaryformatter class like you also would use with normal classes.

Frans Bouma | Lead developer LLBLGen Pro
mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 10-Jul-2006 13:29:11   

Otis wrote:

TypedView's are datatables.

so if you want them in XML, in .NET 1.x, add them to a dataset and serialize the dataset with writexml. If you're in .NET 2.0, you can use the WriteXml method on the datatable, which is the base class of the typedview class.

Binary serialization is supported as well, simply use the binaryformatter class like you also would use with normal classes.

Your response is appreciated.

However, given some other research and the current answer, the matter is now a bit confused.

One can read about the DataSet-Based-Serialization in this thread...

http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=523&HighLight=1

...however, in that thread seems to suggest something different than using a DataSet-Based-Serialization and that one SHOULD rather use the following detail...

TypedView's are marked 'serializable'... [they] are serializable, directly"

...and, furthermore, that thead it seems to suggest explicitly that one SHOULD NOT to use a DataSet, as noted in the following line strikeout...

TypedViews should be added to a new, empty dataset and then be serialized. I realize this is not optimal...

Now, in this current thread, it says that one SHOULD use a DataSet.

Therefore, it seems that we may have some conflicting suggestions.

Maybe it is the case that either way (DataSet-Based-Serialization or Direct-Serialization) can be used.

If possible, can you clarify this a bit?

Is there a preferred or suggested way to do it?

What is the easiest way to do it from a coding perspective?

What is the way that performs fastest?

Please advise.

Thank you VERY much.

-- Mark Kamoski

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 10-Jul-2006 15:03:25   

I think they are not conflicting, both suggest the use of a dataset.

The omitted line contained the following words "I realize this is not optimal". Which was omitted and it was not the reason for the omitting as it may seem.

And it was followed by the following lines:

TypedView's are marked 'serializable'. They have a protected deserialize constructor, which works ok. DataTable does implement ISerializable already, but because it is not marked as serializable, it can't be serialized directly. (this is done by the dataset).

If you re-read the entire post again it may be clearer now:

~~dLists are serializable by default, as they implement ISerializable through their base class (which does custom serialization, due to the fact that it has to serialize the ObeyWeakRelations setting too, which would otherwise not be serialized)

TypedViews should be added to a new, empty dataset and then be serialized. I realize this is not optimal. I'll try to fix this in 1.0.2003.3.~~

I definitely need a break , I start to forget what the stuff can do!

TypedView's are marked 'serializable'. They have a protected deserialize constructor, which works ok. DataTable does implement ISerializable already, but because it is not marked as serializable, it can't be serialized directly. (this is done by the dataset).

mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 10-Jul-2006 15:26:46   

Walaa wrote:

I think they are not conflicting, both suggest the use of a dataset...

OK. That's great. I was wrong. I apparently misread the post. Thanks for clearing that up. I appreciate it very much.

Now, there is another (closely related) matter. Since a TypedView has a DataTable as a base class, it is easy to convert a TypedView object into a DataTable object. Fine. But, one will probably need to refeverse the process too.

The question is...

How can/should one convert a DataTable back into a TypedView?

It looks like a DirectCast will not work. It looks like one has to iterate and use TypedView.ImportRow() to import every row from the DataTable into the TypedView, one at a time. This is fine (I suppose) and seems to work (so far). What the best/ suggested/ correct way is is not clear. Also, one notes that a TypedView has a base class of DataTable but it also implements at least one interface-- so, that could make one wonder whether or not the row-by-row import process loses any information.

Please advise.

Thank you.

-- Mark Kamoski

See the code below for more details.


Public Shared Function GetRuleSetDetailTypedView() As TypedViewClasses.BreRuleSetDetailTypedView
    Dim myTypedView As TypedViewClasses.BreRuleSetDetailTypedView = Nothing

    'Get an instance of the service.
    Dim myService As AdminService.AdminService = Common.AdminServiceAdapter.GetService()

    'Get the XML.
    Dim myTypedViewXml As String = myService.GetRuleSetDetailTypedViewXml()

    'Convert the XML back into a DataTable.
    Dim myDataTable As DataTable = Common.AdminServiceAdapter.DeserializeDataTable(myTypedViewXml)

    '...but, how doe we get the DataTable back into the TypedView???

    '...unfortunately, this does not work... cast is not valid...
    'myTypedView = DirectCast(myDataTable, TypedViewClasses.BreRuleSetDetailTypedView)

    '...so, it looks like one has to add the data row-by-row, something like this...

    myTypedView = New TypedViewClasses.BreRuleSetDetailTypedView

    For Each myDataRow As DataRow In myDataTable.Rows
        myTypedView.ImportRow(myDataRow)
    Next

    Return myTypedView
End Function

mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 10-Jul-2006 15:30:13   

Otis wrote:

TypedView's are datatables.

so if you want them in XML, in .NET 1.x, add them to a dataset and serialize the dataset with writexml. If you're in .NET 2.0, you can use the WriteXml method on the datatable, which is the base class of the typedview class.

Binary serialization is supported as well, simply use the binaryformatter class like you also would use with normal classes.

I don't know if you noticed it, so I will highlight this friendly suggestion...

Suggestion for future enhancement... ...add ReadXml() and WriteXml() methods to the TypedView, to make things easy to use and to make things uniform with Entity and EntityCollection APIs.

...so, please consider that.

(Of course, whether or not that suggestion is implemented, LLBLGen is a great product.)

Also, any help that you (or anyone) can be with the "how to convert a DataTable to a TypedView" question (above) would be greatly appreciated.

Thank you.

-- Mark Kamoski

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 10-Jul-2006 16:36:47   

mkamoski wrote:

Otis wrote:

TypedView's are datatables.

so if you want them in XML, in .NET 1.x, add them to a dataset and serialize the dataset with writexml. If you're in .NET 2.0, you can use the WriteXml method on the datatable, which is the base class of the typedview class.

Binary serialization is supported as well, simply use the binaryformatter class like you also would use with normal classes.

I don't know if you noticed it, so I will highlight this friendly suggestion...

Suggestion for future enhancement... ...add ReadXml() and WriteXml() methods to the TypedView, to make things easy to use and to make things uniform with Entity and EntityCollection APIs.

...so, please consider that.

I don't have to, in .NET 2.0 these are already there simple_smile . In .NET 1.x they're not, but you can easily create XML from a typedview by using a dummy dataset: DataSet dummy = new DataSet(); dummy.Tables.Add(myTypedView); dummy.WriteXml(myXmlStream);

(Of course, whether or not that suggestion is implemented, LLBLGen is a great product.) Also, any help that you (or anyone) can be with the "how to convert a DataTable to a TypedView" question (above) would be greatly appreciated.

Downcasting to type B if B is a subtype from A and the instance you want to cast is of type A isn't possible, you've to migrate the data.

So you then create a new TypedView instance of the typedview of your choice, and import the rows into that one from the datatable.

Frans Bouma | Lead developer LLBLGen Pro
mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 10-Jul-2006 17:00:18   

[quotenick="Otis"]

I don't have to, in .NET 2.0 these are already there simple_smile . In .NET 1.x they're not, but you can easily create XML from a typedview by using a dummy dataset: DataSet dummy = new DataSet(); dummy.Tables.Add(myTypedView); dummy.WriteXml(myXmlStream);

OK. That is good news. great.

Downcasting to type B if B is a subtype from A and the instance you want to cast is of type A isn't possible, you've to migrate the data. So you then create a new TypedView instance of the typedview of your choice, and import the rows into that one from the datatable.

OK. This is also good news because that's what I thought.

Thank you.

-- Mark Kamoski

mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 10-Jul-2006 17:04:56   

All --

FWIW, as a follow-up to this thread, below are the Serialize/Deserialize methods that we are currently using for DotNet1 and Llblgen1 stuff.

Note that this code is not yet completely tested; but, it does seem to work.

(Comment, criticisms, suggestions, changes, and so on are welcome and appreciated.)

HTH.

Thank you.

-- Mark Kamoski

DeserializeDataTable


''' -----------------------------------------------------------------------------
''' <summary>
''' This will deserialize a non-empty String and return it as a DataTable.
''' </summary>
''' <param name="dataTableObject">This is target of the deserialization.</param>
''' <returns>This is the result of the deserialization.</returns>
''' <remarks>
''' Note that a DataTable will not serialize directly; therefore, a DataSet is used.
''' Note that since a DataSet is used, it is implied that there is exactly 1 DataTable in the DataSet.
''' Note that SerializeDataTable and DeserializeDataTable are companion methods.
''' </remarks>
''' -----------------------------------------------------------------------------
Public Shared Function DeSerializeDataTable(ByVal dataTableObject As String) As DataTable
    Dim myDataTable As DataTable = Nothing
    Dim myStringReader As StringReader = Nothing
    Dim myXmlReader As XmlTextReader = Nothing

    Try
        dataTableObject = dataTableObject & ""
        dataTableObject = dataTableObject.Trim()

        If (dataTableObject.Length <= 0) Then
            Throw New System.ArgumentNullException("dataTableObject")
        Else
            'Continue.
        End If

        myStringReader = New StringReader(dataTableObject)
        myXmlReader = New XmlTextReader(myStringReader)
        Dim myDataSet As DataSet = New DataSet
        myDataSet.ReadXml(myXmlReader)
        Debug.WriteLine("myDataSet.Tables.Count.ToString() = " & myDataSet.Tables.Count.ToString())

        'Serializing an empty DataTable destroys it; so, put it back here if it is gone.
        If (myDataSet.Tables.Count > 0) Then
            'Continue.
        Else
            myDataSet.Tables.Add(New DataTable)
        End If

        myDataTable = myDataSet.Tables(0).Copy()
    Finally
        If (Not myXmlReader Is Nothing) Then
            myXmlReader.Close()
        End If

        If (Not myStringReader Is Nothing) Then
            myStringReader.Close()
        End If
    End Try

    Return myDataTable
End Function

SerializeDataTable


''' -----------------------------------------------------------------------------
''' <summary>
''' This will serialize the given non-null DataTable and return it as a String.
''' </summary>
''' <param name="dataTableObject">This is the object to be serialized.</param>
''' <returns>This is the result of the serialization.</returns>
''' <remarks>
''' Note that a DataTable will not serialize directly; therefore, a DataSet is used.
''' Note that since a DataSet is used, it is implied that there is exactly 1 DataTable in the DataSet.
''' Note that SerializeDataTable and DeserializeDataTable are companion methods.
''' </remarks>
''' -----------------------------------------------------------------------------
Public Shared Function SerializeDataTable(ByVal dataTableObject As DataTable) As String
    Dim myXml As String = ""
    Dim myStringWriter As System.IO.StringWriter = Nothing

    Try
        If (dataTableObject Is Nothing) Then
            Throw New System.ArgumentNullException("dataTableObject")
        Else
            'Continue.
        End If

        Dim myDataSet As DataSet = New DataSet
        myDataSet.Tables.Add(dataTableObject)
        myStringWriter = New IO.StringWriter
        myDataSet.WriteXml(myStringWriter)
        myStringWriter.Flush()
        myXml = myStringWriter.ToString()
    Finally
        If (Not myStringWriter Is Nothing) Then
            myStringWriter.Close()
            myStringWriter = Nothing
        End If
    End Try

    Return myXml
End Function

Note-- This post was edited by mkamoski as of 2006-Jul-20 13:05 GMT-0500, to fix the DeSerialize method a bit because .NET Serialization of an empty DataTable actually destroys that DataTable; so, a tweak is needed.