картографирование System.Version с помощью NHibernate 1.2 - PullRequest
3 голосов
/ 05 января 2010

У меня есть объект, который использует System.Version в качестве свойства. Я хочу, чтобы этот объект был отображен в моей таблице, сохраняя версию в виде строки. Каков наилучший способ сделать это с NHibernate v1.2?

public class MyClass
{
  public Version MyVersion {get; set;}
}

не уверен, что делать с правильным отображением

это дает мне сообщение об ошибке «Недопустимая попытка GetBytes для столбца MyVersion0_0_». Функция GetBytes может использоваться только для столбцов типа Text, NText или Image. Если я использую type = "string" на карте, я получаю ошибки приведения.

предложения?

Ответы [ 4 ]

4 голосов
/ 05 января 2010

Вам необходимо написать тип пользователя NHibernate, который возвращает значение свойства типа Version, но сохраняется в виде строки. Здесь есть скелетная реализация типа пользователя здесь , которая позаботится о некоторых работах для вас.

2 голосов
/ 06 января 2010

Еще один ответ на вопрос Дэвида М. Однако вы заметите, что System.Version имеет конструктор, который принимает строковое представление, а также ToString(), который производит тот же формат, так что вы можете отобразить свойство как простую строку в NHibernate и сопоставить его с частным напрямую к строковому полю, затем введите свойство фасада в System.Version примерно так:

public System.Version Version
{
    get { return new System.Version(_versionAsString); }
    set { _versionAsString = value.ToString(); }
}

Я не считаю это особенно плохой практикой, и это достаточно легко сделать. Возможно, вам придется использовать внутреннее свойство, а не поле, если вы собираетесь использовать прокси-тип для отложенной загрузки, но в противном случае оно должно работать.

2 голосов
/ 05 января 2010

Предложение Дэвида М и ссылка на статью были великолепны. На тот случай, если у кого-то еще возникнут проблемы с доступом на этот сайт (мне пришлось загрузить его из кеша Google), вот мое решение:


    public abstract class BaseImmutableUserType : IUserType
    {
        public abstract object NullSafeGet(IDataReader rs, string[] names, object owner);
        public abstract void NullSafeSet(IDbCommand cmd, object value, int index);
        public abstract SqlType[] SqlTypes { get; }

        public new bool Equals(object x, object y)
        {
            if (ReferenceEquals(x, y))
            {
                return true;
            }

            if (x == null || y == null)
            {
                return false;
            }

            return x.Equals(y);
        }

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

        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 DeepCopy(cached);
        }

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

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

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

    public class VersionUserType: BaseImmutableUserType
    {

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

        public override object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            Version version = null;
            var value = NHibernateUtil.String.NullSafeGet(rs, names) as string;
            if (value != null)
                version = new Version(value);
            return version;
        }

        public override void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            object valueToSet;
            Version version = value as Version;
            if (version != null)
            {
                valueToSet = version.ToString();
            }
            else
            {
                valueToSet = DBNull.Value;
            }

            NHibernateUtil.String.NullSafeSet(cmd, valueToSet, index);
        }
    }

и файл сопоставления теперь имеет это свойство:

0 голосов
/ 05 января 2010

Ответ Дэвида М., вероятно, самый надежный способ сделать это.

В качестве альтернативы вы можете преобразовать свойство в строку и просто использовать его. Я не уверен, насколько велико изменение, которое есть в вашей модели.

...