Q: Can I use NHibernate to store an object in xml serialized form? 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; }
}


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:


*

*Working with XML Fields in NHibernate

*Another XML implementation of IUserType

A: I had the same idea to save object in XML column. My idea was other. I took code from links and changed it to generic IUserType implementation. So any field/prop which is [Serializable] can be saved in XML column.
public class XmlUserType<T> : IUserType where T : class
{
  public new bool Equals(object x, object y)
  {
    return x == y;
  }

  public int GetHashCode(object x)
  {
    return x.GetHashCode();
  }

  public object NullSafeGet(IDataReader rs, string[] names, object owner)
  {
    if (names.Length != 1)
      throw new InvalidOperationException("names array has more than one element. can't handle this!");

    var val = rs[names[0]] as string;

    if (string.IsNullOrWhiteSpace(val) == false)
    {
      return KRD.Common.GenericXmlSerialization.Deserialize<T>(val);
    }

    return null;
  }

  public void NullSafeSet(IDbCommand cmd, object value, int index)
  {
    var parameter = (DbParameter)cmd.Parameters[index];
    T toSave = value as T;

    if (toSave != null)
    {
      parameter.Value = KRD.Common.GenericXmlSerialization.Serialize(toSave);
    }
    else
    {
      parameter.Value = DBNull.Value;
    }
  }

  public object DeepCopy(object value)
  {
    T toCopy = value as T;

    if (toCopy == null)
      return null;

    string serialized = KRD.Common.GenericXmlSerialization.Serialize(toCopy);

    return KRD.Common.GenericXmlSerialization.Deserialize<T>(serialized);
  }

  public object Replace(object original, object target, object owner)
  {
    throw new NotImplementedException();
  }

  public object Assemble(object cached, object owner)
  {
    var str = cached as string;
    if (string.IsNullOrWhiteSpace(str) == false)
    {
      return null;
    }

    return KRD.Common.GenericXmlSerialization.Deserialize<T>(str);
  }

  public object Disassemble(object value)
  {
    var toCache = value as T;

    if (toCache != null)
    {
      return KRD.Common.GenericXmlSerialization.Serialize(toCache);
    }

    return null;
  }

  public SqlType[] SqlTypes
  {
    get
    {
      return new SqlType[] { new SqlXmlType() };
    }
  }

  public Type ReturnedType
  {
    get { return typeof(XmlDocument); }
  }

  public bool IsMutable
  {
    get { return true; }
  }
}

public class SqlXmlType : SqlType
{
  public SqlXmlType()
    : base(DbType.Xml)
  {
  }
}

Usage with FluentNHibernate:
  public class MainObject
  {
    public int Id { get; set; }

    public ObjectAsXml Data { get; set; }
  }

  public class ObjectAsXml
  {
    public string Name { get; set; }

    public int Date { get; set; }

    public ObjectAsXml OtherObject { get; set; }
  }

  private class MainObjectMap : ClassMap<MainObject>
  {
    public MainObjectMap()
    {
      Id(id => id.Id);
      Map(m => m.Data).CustomType<XmlUserType<ObjectAsXml>>().Nullable();
    }
  }

Maybe it will help somebody.
