旱由 发表于 2025-5-29 14:58:38

自定义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,它和标记 的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: }    想象一下,当中的“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.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 as DbParameter;    15:   param.Value = type.Ticks;    16: }这3个方法无需多解释。
 
源码在http://leodemo.googlecode.com/svn/trunk/NHibernate/NHibernate.ExtendTypes ,请用SVN客户端工具获取


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 自定义NHibernate映射类型