views:

475

answers:

2

I have a DataTable with rows of data. I have a class with properties that match the row column names.

How can I have a List that is populated from the DataTable Row information?

Do I call something like (MyType)new XmlSerializer(typeof(MyType)).Deserialize(new XMLReader(Table.WriteXML()));

+1  A: 

If I understand your question correctly, you want to put the fields of each row of data into instances of YourClass and then store the instances in a List?

In that case, the most straightforward way is to

create the List object
loop over the rows
   create a new YourClass object
   map the fields to the properties of the YourClass object
   add the YourClass object to the list
d91-jal
I just thought there may be a quicker way with the XMLSerializer class but not sure there is
Jon
By 'quicker', do you mean, 'generic'?
Jeff Sternal
I guess? Previously I have had XML and used the XMLSerilaizer but that is when I only had one instance of it. In this approach I now have X amount of rows and therefore want a List<MyType>.
Jon
+2  A: 

I recommend writing classes to perform this transformation instead of using XML serialization, which requires a lot of extra work and ties your objects too closely to your data model.

On the other hand, sometimes you just have to deserialize collections from XML. To accomplish this, all you need to do is tell the XmlSerializer which node to map to the collection.

By default, DataTable.WriteXml creates a root element called <DocumentElement>. For example, if you write from a DataTable called "Name" that has "FirstName" and "LastName" columns, you'll get this:

<DocumentElement>
    <Name>
        <FirstName>Jon</FirstName>
        <LastName>User</LastName>
    </Name>
</DocumentElement>

The problem is that the XmlSerializer doesn't know that "DocumentElement" should be deserialized to your collection class. There are two ways to tell it how.

By Convention

The XmlSerializer knows that a root element named "ArrayOfMyClass" should map to collections of MyClass.

Add your DataTable to a DataSet named "ArrayOfMyClass" to serialize it like this ...

<ArrayOfMyClass>
    <MyClass>
    // ... elements that map to properties of MyClass
    </MyClass>
</ArrayOfMyClass>

.... which deserializes into a List<MyClass> as desired.

By Hand

As an alternative, you can do it like this:

XmlRootAttribute root       = new XmlRootAttribute("DocumentElement");
XmlSerializer    serializer = new XmlSerializer(typeof(List<Name>), root);

Presuming everything else is ok (that is, your data row column names match your class' property names), this will deserialize as expected into your List<MyClass>.

Edit: note that this approach has a rather severe problem (with a moderately cumbersome workaround) described in this SO question: XmlSerializer Performance Issue.

Jeff Sternal
Thanks for your help. I used the example below in the end because as you say I am creating more work however you answered my question! Thanks
Jon
No problem - I just discovered an ugly problem with one of the approaches I suggested (though it has a workaround), which I've linked above. All the better that you chose the non-XML-oriented implementation. :)
Jeff Sternal