картографическая система.Версия с NHibernate 1.2


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

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

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

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

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

4 3

4 ответа:

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

Предложение Дэвида м и ссылка на статью были замечательными. На всякий случай, если у кого-то еще возникнут проблемы с доступом к этому сайту (мне пришлось загрузить его из кэша 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);
        }
    }

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

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

public System.Version Version
{
    get { return new System.Version(_versionAsString); }
    set { _versionAsString = value.ToString(); }
}
Я не считаю это особенно плохой практикой, и это достаточно легко сделать. Возможно, Вам потребуется использовать внутренний свойство, а не поле, если вы собираетесь прокси-тип для ленивой загрузки, но в противном случае он должен работать.

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

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