Отображение nHibernate на пользовательские типы
-
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).