Make the user type immutable by returning false in IsMutable
and just throw an exception in SetPropertyValue
.
I have something similar, but with an own datatype instead of DateTimeOffset
. I just adapted the code for you. It stores the date as UTC time and the offset as TimeSpan
(stores Ticks. Of course you don't need this resolution. But, you should not store whole hours for time zones, there are time zones offsets with fractions of hours!! And TimeSpan
is build in an works out of the box.)
public class DateTimeOffsetUserType : ICompositeUserType
{
public bool IsMutable
{
get { return false; }
}
public void SetPropertyValue(object component, int property, object value)
{
throw new InvalidOperationException("Immutable, SetPropertyValue is not allowed");
}
public object NullSafeGet(System.Data.IDataReader dr, string[] names, NHibernate.Engine.ISessionImplementor session, object owner)
{
if (dr == null)
{
return null;
}
DateTime? utcTime;
TimeSpan? offset;
utcTime = (DateTime?)PropertyTypes[0].NullSafeGet(dr, names[0], session, owner);
offset = (TimeSpan?)PropertyTypes[1].NullSafeGet(dr, names[1], session, owner);
if (utcTime == null || offset == null) return null;
return new DateTimeOffset(utcTime.Value, offset.Value);
}
public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index, NHibernate.Engine.ISessionImplementor session)
{
if (value == null)
{
NHibernateUtil.Timestamp.NullSafeSet(cmd, null, index);
NHibernateUtil.TimeSpan.NullSafeSet(cmd, null, index + 1);
}
else
{
DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
PropertyTypes[0].NullSafeSet(cmd, dateTimeOffset.UtcDateTime, index, session);
PropertyTypes[1].NullSafeSet(cmd, dateTimeOffset.Offset, index + 1, session);
}
}
// other methods