views:

1010

answers:

1

Say I have a class like this:

public class MyClass
{
    public int Id { get; set; }

    public DateTime Date { get; set; }
    public string String1 { get; set; }
    public string String2 { get; set; }
    public string String3 { get; set; }
    public string String4 { get; set; }
}

Is it possible to get NHibernate to store it in the following schema?

CREATE TABLE [dbo].[MyClass](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Xml] [varchar](max) NOT NULL,
)

Where the Id maps to Id, but then all other fields get serialized into XML (or otherwise)? I don't mind if these other fields have to go on a child object like the below, if that helps:

public class MyClass
{
    public int Id { get; set; }

    public AllOtherOptions Options { get; set; }
}

public class AllOtherOptions
{
    public DateTime Date { get; set; }
    public string String1 { get; set; }
    public string String2 { get; set; }
    public string String3 { get; set; }
    public string String4 { get; set; }
}
+2  A: 

I am thinking about doing something similar for an upcoming project. The project requires collecting a lot of data but only a few elements need to be stored in a relational database. I haven't started experimenting but these are my thoughts so far.

You can map an XML data type by creating a type that implements IUserType. If the child class (AllOtherOptions) is serializable, you should be able to map the XML field as a private member in MyClass and serialize/deserialize AllOtherOptions as needed. You could either dynamically maintain the XML field (sounds like a lot of work) or create an interceptor to do it. My thinking is that MyClass would implement an interface such as

public interface IXmlObjectContainer
{
    void SerializeChildObjects();
    void DeSerializeChildObjects();
}

and the interceptor would call those methods as needed. That's a proof of concept idea. I would probably refine that by exposing pairs of xml fields and serializable objects to remove the work of serializing from IXmlObjectContainer implementers. Or maybe handle serialization through the XML field's get/set accessors.

More info:

  1. Working with XML Fields in NHibernate
  2. Another XML implementation of IUserType
Jamie Ide
Sounds like a fairly elegant solution; I like it.
Stuart Childs
I found that if your type is marked with [Serializable], if you add "type="serializable"" to your mapping, NH automatically binary(de)serializes it for you, which did the job for me, thanks for the links tho +1
Andrew Bullock
Interesting. I think this only works on SQL Server because it stores XML as BLOB data (http://msdn.microsoft.com/en-us/library/ms345117.aspx) and serializable maps to DbType.Binary (http://nhforge.org/doc/nh/en/index.html#mapping-types).
Jamie Ide