Отображение nHibernate на пользовательские типы - PullRequest
13 голосов
/ 28 октября 2008

У меня есть база данных Oracle, и одно из полей является полем диапазона дат. В основном он просто сохраняется в базе данных как VARCHAR (40) в формате ГГГГ / ММ / ДД-ГГГГ / ММ / ДД. Я хочу сопоставить его в 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; }
}

Как мне сопоставить пользовательские классы, подобные этой?

1 Ответ

18 голосов
/ 28 октября 2008

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

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

В 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, чтобы получить правильный экземпляр TypeClass, а затем фактически возвращает этот экземпляр. Процесс разрешения типов происходит прозрачно с моими классами доступа к данным (и даже с самим NHibernate).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...