One of the things I’ve been working on recently involves using XML columns in SQL Server. Starting out, it was simple and I was just doing vanilla ADO.NET (wrapped in a simple Query API) combined with XML serialization/deserialization, which worked pretty well for a while.
But as the complexity has grown, it seemed like too much time was being spent enhancing the persistence infrastructure in this particular area of the application. In comes NHibernate, which is already integrated and available to me on this particular project. In fact, the only reason I didn’t use NHibernate for this particular feature from day one is because I didn’t see a lot of information available regarding NHibernate and XML columns. I did find one old blog post by Ayende and a seemingly outdated article on the NHibernate site. But I admit I’ve never jumped into creating custom user types in NHibernate and wasn’t yet comfortable moving forward with that approach. Since what I needed at the time was pretty simple, I went forward without NHibernate for the time being.
Without going into too much detail, I came to a point where I wanted to spike with NHibernate to see how it handles columns with an XML data type. I’ve only tried one of a couple approaches so far, but wanted to get some feedback on it so far.
First, a couple goals:
- Store a set of data as XML in a SQL Server XML column
- Ability to deserialize the XML into strongly typed objects for use in the rest of the code base
Warning: contrived example ahead. The real implementation is basically for lightweight messages.
1: public class Person
3: private readonly string contactInformationXml;
5: public Person(ContactInformation contactInformation)
7: // NOTE: SerializeToXmlStream extension method not shown
8: contactInformationXml =
9: new StreamReader(contactInformation.SerializeToXmlStream()).ReadToEnd();
12: public ContactInformation GetContactInformation()
14: var xmlDocument = new XmlDocument();
17: // NOTE: DeserializeInto extension method not shown
18: return xmlDocument.DeserializeInto<ContactInformation>();
And an excerpt from an example NHibernate mapping for this:
1: <property name="ContactInformationXml" column="ContactInformation"
2: type="String" not-null="true" access="field.camelcase" />
So in the Person class above, the constructor accepts a strongly typed component for the contact information, serializes it to XML and stores it in a private field as a string. Then the NHibernate mapping takes care of persisting the serialized string to the XML column named ContactInformation in the database. To see how it would get used when NHibernate loads a Person, the GetContactInformation() method is an example of deserializing the string into the strongly typed ContactInformation object which it then returns.
Now, putting aside the reasons for or against using XML in this way, using XML columns in general or the fact that serialization concerns shouldn’t be placed inside a class like this…
I’m looking for feedback on this approach and if anyone else has any better ways of doing this. I’ve yet to go down the path of creating a custom NHibernate user type, even though I think doing it that way would be a bit cleaner and flexible in the future.
Anyone have any other good examples of using NHibernate for persisting data to XML columns?