This is a migrated thread and some comments may be shown as answers.

XML serialization of parent and children

4 Answers 551 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Craig
Top achievements
Rank 1
Craig asked on 09 Apr 2013, 11:08 AM
Hello,
I want to export a parent table and its child table to XML but XMLSerializer's Serialize method ignores the child Navigational Property because it is implemented as an IList<childtype> so all I get exported is the parent table's data.

Can I configure the ORM model so that the generated classes implement the Navigational Property as a List<childtype> instead or is there a better way ?

EDIT:
I've found the How to: Customize Collection Generation (C#) in the OpenAccess ORM Programmers Guide. I'd like to just change the code generation for the required entity. I guess the documented approach will apply to all entities? If I change the generation to use List<> instead of IList<> what will I lose?


Thanks
Craig

4 Answers, 1 is accepted

Sort by
0
Kaloyan Nikolov
Telerik team
answered on 10 Apr 2013, 03:42 PM
Hi Craig,

 
Due to the fact that Telerik OpenAccess ORM enhances the generated properties and changes some of the code inside them, there are some things to be considered. The preferred way to get a persistent type serialized is described here. The example in the article uses the old OpenAccess API but the approach is still valid, just ignore the code examples in the Program.Main() method.

In short you don't need to customize the code generation templates to serialize child lists. You can extent the classes you want to be serialized with a partial class and add only one additional property which will be used by the XmlSerializer.

Example:

public partial class User
{
    [XmlElement(ElementName="SerializedRoles")]
    public XMLList<Role> MyRoles
    {
        get
        {
            return new XMLList<Role>(Roles);
        }
        set
        {
            value.Update(Roles);
        }
    }
}

The XMLList class implementation is given in the article. 

Of course you can generate this property with modified T4 template but probably if you don't have too many entities will be faster to just extent them with partial classes.

Please do not hesitate to contact us again if you have any other questions.

All the best,
Kaloyan Nikolov
the Telerik team
Using Encrypted Connection Strings with Telerik OpenAccess ORM. Read our latest blog article >>
0
Craig
Top achievements
Rank 1
answered on 11 Apr 2013, 11:31 AM
Hi Kaloyan,
Thanks for your reply. I had read that part of the help but shied away from it since it was the old API.

I reverted to the default code generation option and removed the T4 templates from my project.  

I've added the XMLList class to my data model project and I've added the XMLList<MyType> MyTypes public property to my partial class.
I presumed the Roles argument in your example is the public IList property to be serialised so I renamed it to my public IList property.

However, the XML serialisation fails in the XMLList's IXmlSerializable.WriteXml method with a stack overflow exception when the XMLSerializer's Serialize method is called. Here's an extract of my code:

List<MyParent> parentList = new List<MyParent>(ParentObCol);
TextWriter myStreamWriter = new StreamWriter(spaceMapFile);
Type[] extraTypes = new Type[1];
extraTypes[0] = typeof(List<myChildren>);
XmlSerializer mySerializer = new XmlSerializer(typeof(List<MyParent>), extraTypes);
mySerializer.Serialize(myStreamWriter, parentList);
myStreamWriter.Close();

What do you think I've done wrong?
Regards,
Craig
0
Accepted
Kaloyan Nikolov
Telerik team
answered on 11 Apr 2013, 04:06 PM
Hi Craig,

The code looks good. This exception could happen because of circular references between the objects in the object graph. Unfortunately the XmlSerializer doesn't support circular references, you should handle that manually. 

I can suggest you two approaches in this case:
1. If you have navigation properties from both sides, consider removing the single navigation property. This should brake the circular reference. You can do that from the Association Editor by disabling the Source End checkbox.

2. Remove the properties added previously and  serialize both collections (all parent objects and all child objects) separately without the navigation properties. When you deserialize the objects you can re-link them by Id = foreignKeyId. Unfortunately this will require some manual work. This approach can by taken if your entities graph is relatively simple and stable. 

Hope that helps.

Greetings,
Kaloyan Nikolov
the Telerik team
Using Encrypted Connection Strings with Telerik OpenAccess ORM. Read our latest blog article >>
0
Craig
Top achievements
Rank 1
answered on 11 Apr 2013, 05:02 PM
Kaloyan, you're a genius. Option 1 resolved it.

Thanks
Craig
Tags
Development (API, general questions)
Asked by
Craig
Top achievements
Rank 1
Answers by
Kaloyan Nikolov
Telerik team
Craig
Top achievements
Rank 1
Share this question
or