代码之家  ›  专栏  ›  技术社区  ›  Craig

nHibernate映射到自定义类型

  •  13
  • Craig  · 技术社区  · 16 年前

    我有一个Oracle数据库,其中一个字段是日期范围字段。它基本上是以varchar(40)的形式存储在数据库中的,格式为yyyy/mm/dd-yyyy/mm/dd。我想用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; }
    }
    

    如何映射到这样的自定义类?

    1 回复  |  直到 16 年前
        1
  •  18
  •   TheSoftwareJedi jac    16 年前

    您需要实现自己的iuserType。

    看到这个 blog post 详情。我还将粘贴下面的相关部分,以防博客消失。

    在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映射中将actualClass和typeClass之间的关联显式映射为简单属性。

    <property
      name="Type"
      column="TypeName"
      type="Samples.NHibernate.DataAccess.TypeClassUserType, 
            Samples.NHibernate.DataAccess" />
    

    由于nhibernate正在保存actualtype的实例,它将加载并创建一个新的typeClassUserType实例,并调用nullsafeset方法。从方法体中可以看到,我只是从映射属性中提取名称(作为值参数传入),并将提取的名称设置为要在数据库中设置的参数的值。最终结果是,尽管实际类的type属性在域模型中是typeclass,但只有typeclass对象的name属性存储在数据库中。反之亦然。当nhibernate从数据库加载actualtype的实例,并查找自定义映射类型的属性时,它将加载自定义类型并调用nullsafeget方法。如您所见,我的方法从返回的数据中获取名称,调用我的flyweight工厂以获取正确的typeclass实例,然后实际返回该实例。类型解析过程对我的数据访问类(甚至对NHibernate本身)透明地发生。