Using NHibernate ICompositeUserType with a value type

后端 未结 3 2022
名媛妹妹
名媛妹妹 2021-01-12 00:15

I have a domain model object which has properties of type System.DateTimeOffset. I\'m using a database which doesn\'t support this type natively, so I\'m planning to store i

3条回答
  •  北恋
    北恋 (楼主)
    2021-01-12 01:06

    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
    

提交回复
热议问题