自定义NHibernate映射类型

     由于项目需要,需要一个Time结构,因为需要和DateTime对象进行换算,因此是一个采取和DateTime一样的Tickets方式保存数值,在数据库保存的是long型。因为不想为了Mapping而污染Domain,所以就增加自定义射的对象TimneType。

      因为一个Time对象只需要一个Column保存,并且是一个值类型,所以没有从IUserType继承,而选择了NHibernate.Type.PrimitiveType。PrimitiveType 是NHibernate用于扩展ValueType的基类。

      其实重写非常简单。基本不需要太多的NHibernate知识就可以完成。不过抱着折腾的态度),还是说说几个关键属性。

 

DefaultValue

 

很简单返回的是new Time。

   1: public override object DefaultValue
   2: {
   3:    get { return new Time(); }
   4: }

 

      这个DefaultValue用到的地方是UnsavedValueFactory.GetUnsavedIdentifierValue,它和标记<id> 的unsave-value有关,根据文档的解释,我认为NHibernate在不设定unsave-value的情况下, 会把DefaultValue作为unsave-value。如果Object的Id和DefaultValue相同,就会执行Insert,否则就是update。DefaultValue只有在把Time作为Id的情况下才会有用。

object FromStringValue(string xml)

这个方法明显地是把String变为Time类型。而且也是和unsave-value有关的。先看代码,如下

   1: public override object FromStringValue(string xml)
   2: {
   3:    return new Time(long.Parse(xml));
   4: }

    想象一下,当<id unsave-value=“0” >中的“0”是怎样变为Time对象了?

 

PrimitiveClass

也是很简单返回Int32,也就是对应数据库的.net基础类型。

   1: public override System.Type PrimitiveClass
   2: { 
   3:         get { return typeof (Int32); } 
   4: }

    这个属性是用在Time集合,如Array,List等,在保存到数据库的过程中,提示NHibernate,集合中是Int32类型。除非Time的映射是用在Array这类集合,否则还不会被调用。

 

ReturnClass

返回一个Time类型。这个非常重要,在NHibernate调用过程中,是必须的。

   1: public override System.Type ReturnedClass
   2: {
   3:    get { return typeof (Time); }
   4: }

 


string ObjectToSQLString(object value, Dialect.Dialect dialect);

      下面的代码的返回值,在NHibernate的生成SQL的过程中,会作为SQL的一部分使用。如 select * from Table1 where time=0 中的where 后面部分内容。

   1: public override string ObjectToSQLString(object value, Dialect.Dialect dialect)
   2: { 
   3:    var val = (Time) value;
   4:    return val.Ticks.ToString();
   5: }

     如果数据库中的Column是字符类型,需要在返回值加上单引号,如 "’”+value+”’”,否则查询的Sql会出错。因为Time在数据库中是数值型,所以不需要加。

 

剩下3个方法两个Get及Set方法,如下

   1: public override object Get(IDataReader rs, string name)
   2: {
   3:     return new Time(Convert.ToInt32(rs[name].ToString()));
   4: }
   5:  
   6: public override object Get(IDataReader rs, int index)
   7: {
   8:     return new Time(rs.GetInt32(index));
   9: }
  10:  
  11: public override void Set(IDbCommand cmd, object value, int index)
  12: {
  13:     var type = (Time) value;
  14:     var param = cmd.Parameters[index] as DbParameter;
  15:     param.Value = type.Ticks;
  16: }

这3个方法无需多解释。

 

源码在http://leodemo.googlecode.com/svn/trunk/NHibernate/NHibernate.ExtendTypes ,请用SVN客户端工具获取

posted @ 2009-10-27 23:07 沉默的糕点 阅读(...) 评论(...) 编辑 收藏