Подтвердить что ты не робот

NHibernate-сопоставление для пользовательских типов

У меня есть база данных Oracle, а одно из полей - поле диапазона дат. Он в основном просто хранится в базе данных как VARCHAR (40) в формате YYYY/MM/DD-YYYY/MM/DD. Я хочу сопоставить его в nHibernate с пользовательским классом, который я создал таким образом

public class DateTimeRange
{
    public DateTimeRange(DateTime fromTime, DateTime toTime)
    {
        FromTime = fromTime;
        ToTime = toTime;
    }

    public override string ToString()
    {
        return String.Format("{0} to {1}", FromTime.ToString("HH:mm:ss"), ToTime.ToString("HH:mm:ss"));
    }

    public DateTime FromTime { get; set; }

    public DateTime ToTime { get; set; }
}

Как я могу сопоставить пользовательские классы следующим образом?

4b9b3361

Ответ 1

Вам нужно реализовать свой собственный IUserType.

Подробнее см. сообщение в блоге. Я также вставлю соответствующий раздел ниже, если блог исчезнет.

В NHibernate настраиваемый тип сопоставления является классом, который происходит из интерфейсов IUserType или ICompositeUserType. Эти интерфейсы содержат несколько методов, которые должны быть реализованы, но для наших целей здесь собирались сосредоточиться на двух из них. Рассмотрим следующее.

  public class TypeClassUserType : IUserType
  {


    object IUserType.NullSafeGet(IDataReader rs, 
      string[] names, 
     object owner) {

     string name = NHibernateUtil.String.NullSafeGet(rs, 
     names[0]) as string;

     TypeClassFactory factory = new TypeClassFactory();
     TypeClass typeobj = factory.GetTypeClass(name);
     return typeobj;
   }

    void IUserType.NullSafeSet(IDbCommand cmd, 
    object value, 
     int index) {

      string name = ((TypeClass)value).Name;
     NHibernateUtil.String.NullSafeSet(cmd, name, index);
    }
  }

Создав этот класс, я теперь могу явно сопоставить ассоциацию между ActualClass и TypeClass как простое свойство для отображения ActualClass.

<property
  name="Type"
  column="TypeName"
  type="Samples.NHibernate.DataAccess.TypeClassUserType, 
        Samples.NHibernate.DataAccess" />

Поскольку NHibernate находится в процессе сохранения экземпляра ActualType, он загрузит и создаст новый экземпляр TypeClassUserType и вызовет метод NullSafeSet. Как вы можете видеть из тела метода, я просто извлекаю имя из сопоставленного свойства (переданного как параметр значения) и устанавливая извлеченное имя как значение параметра, который должен быть установлен в базе данных. Конечным результатом является то, что хотя свойство Type ActualClass является TypeClass в модели домена, в базу данных сохраняется только свойство Name объекта TypeClass. Обратное также верно. Когда NHibernate загружает экземпляр ActualType из базы данных и находит свойство моего настраиваемого типа сопоставления, он загружает мой собственный тип и вызывает метод NullSafeGet. Как вы можете видеть, мой метод получает имя из возвращаемых данных, вызывает мой flyweight factory, чтобы получить правильный экземпляр TypeClass, а затем фактически возвращает этот экземпляр. Процесс разрешения типа выполняется прозрачно для моих классов доступа к данным (и даже для самого NHibernate).