zoukankan      html  css  js  c++  java
  • 自定义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客户端工具获取

  • 相关阅读:
    【iOS】ARC & MRC
    【iOS】判断苹果的设备是哪种
    【iOS】获取项目名和版本号
    CSDN Markdown 超链接
    【iOS】安装 CocoaPods
    【Android Studio】常用快捷键
    Linux初接触设置笔记01
    Java循环输出一个菱形与阶乘倒数
    对象的声明与实例化(转)
    Java堆/栈/常量池以及String的详细详解(转)------经典易懂系统
  • 原文地址:https://www.cnblogs.com/fantasylu/p/1591003.html
Copyright © 2011-2022 走看看