views:

469

answers:

1

Hi

I have a legacy db that I am mapping with Nhibernate. And in several locations a list och strigs or domain objects are mapped as a delimited string in the database. Either 'string|string|string' in the value type cases and like 'domainID|domainID|domainID' in the references type cases.

I know I can create a dummy property on the class and map to that fields but I would like to do it in a more clean way, like when mapping Enums as their string representation with the EnumStringType class.

Is a IUserType the way to go here?

Thanks in advance /Johan

+3  A: 

I am using this:

public class DelimitedList : IUserType
{
    private const string delimiter = "|";

    public new bool Equals(object x, object y)
    {
     return object.Equals(x, y);
    }

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

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
     var r = rs[names[0]];
     return r == DBNull.Value 
      ? new List<string>()
      : ((string)r).SplitAndTrim(new [] { delimiter });
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
     object paramVal = DBNull.Value;
     if (value != null)
     {
      paramVal = ((IEnumerable<string>)value).Join(delimiter);
     }
     var parameter = (IDataParameter)cmd.Parameters[index];
     parameter.Value = paramVal;
    }

    public object DeepCopy(object value)
    {
     return value;
    }

    public object Replace(object original, object target, object owner)
    {
     return original;
    }

    public object Assemble(object cached, object owner)
    {
     return cached;
    }

    public object Disassemble(object value)
    {
     return value;
    }

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

    public Type ReturnedType
    {
     get { return typeof(IList<string>); }
    }

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

SplitAndTrim is my own extension of string. Then in the class (using ActiveRecord for mapping):

[Property(ColumnType = "My.Common.Repository.UserTypes.DelimitedList, My.Common.Repository")]
public virtual IList<string> FooBar { get; set; }
Tim Scott