SQL 2008 HierarchyID support in NHibernate

前端 未结 2 858
梦谈多话
梦谈多话 2020-12-16 11:43

Searched various NHibernate lists and haven\'t come up with a definitive answer. The SQL2008 dialect doesn\'t appear to have support for the HierarchyID data type - new dat

2条回答
  •  南笙
    南笙 (楼主)
    2020-12-16 12:21

    Disclaimer: Im not an NHibernate expert, however, we are using it with Fluent in an upcoming project which uses SQL Server 2008 R2 and Hierarchy IDs. The code below is what we are using currently on our dev environment and is not fully tested/refined. I copied the majority of the code from elsewhere (sorry I lost the link!)

    You need to create a User Defined Type and then use it in your mappings. The mapping below is Fluent, Im not aware how to do it using ActiveRecord but Im guessing it should be similar!

    User Defined Type

    namespace YourNamespace {
        public class SqlHierarchyIdUserType : IUserType {
        public bool Equals(object x, object y) {
            if(ReferenceEquals(x, y))
                return true;
    
            if(x == null || y == null)
                return false;
    
            return x.Equals(y);
        }
    
        public int GetHashCode(object x) {
            return x.GetHashCode();
        }
    
        public object NullSafeGet(IDataReader rs, string[] names, object owner) {
            object prop1 = NHibernateUtil.String.NullSafeGet(rs, names[0]);
    
            if(prop1 == null)
                return null;
    
            return SqlHierarchyId.Parse(new SqlString(prop1.ToString()));
        }
    
        public void NullSafeSet(IDbCommand cmd, object value, int index) {
            if(value == null) {
                ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
            } else {
                if(value is SqlHierarchyId) {
                    SqlHierarchyId hId = (SqlHierarchyId)value;
                    ((IDataParameter)cmd.Parameters[index]).Value = hId.ToString();
                }
            }
        }
    
        public object DeepCopy(object value) {
            if(value == null)
                return null;
    
            var sourceTarget = (SqlHierarchyId)value;
            SqlHierarchyId copy = SqlHierarchyId.Parse(sourceTarget.ToString());
    
            return copy;
    
        }
    
        public object Replace(object original, object target, object owner) {
            return DeepCopy(original);
        }
    
        public object Assemble(object cached, object owner) {
            return DeepCopy(cached);
        }
    
        public object Disassemble(object value) {
            return DeepCopy(value);
        }
    
        public SqlType[] SqlTypes {
            get { return new[] { NHibernateUtil.String.SqlType }; }
        }
    
        public Type ReturnedType {
            get { return typeof(SqlHierarchyId); }
        }
    
        public bool IsMutable {
            get { return true; }
        }
    }
    }
    

    Fluent Mapping

    Map(e => e.YourSqlHierarchyIdProperty)
        .Column("YourSqlHierarchyIdFieldName")
        .CustomType();
    

    Reading this post:

    Castle ActiveRecord: Map to IUserType wihtin Class in C#

    ActiveRecord uses a [Property] attribute to map User Defined Types. So for you it would look something like this:

    public class YourDataObject {
        [Property(ColumnType="YourNamespace.SqlHierarchyIdUserType, YourNamespace")
        public virtual SqlHierarchyId YourSqlHierarchyIdProperty;
    }
    

    Hope it helps!

提交回复
热议问题