Отображение nHibernate на пользовательские типы

StackOverflow https://stackoverflow.com/questions/242022

  •  04-07-2019
  •  | 
  •  

Вопрос

У меня есть база данных 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; }
}

Как я могу сопоставить с пользовательскими классами, как это?

Это было полезно?

Решение

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

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

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

  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).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top