博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

NHibernate 处理 oracle 的long数据类型

Posted on 2010-02-03 19:11  linFen  阅读(1191)  评论(1编辑  收藏  举报

最近利用NHibernate映射类型为Clob字段在插入数据时发现当字符的字节数(一个半角字符一个字节,一个全角字符两个字节)在2000-4000之间时报错(ORA-01461:仅可以插入LONG列的LONG值赋值)。经过不断查找资料和自己的试验该问题终于得到解决,下边我将自己的心得给大家做一个分享。

准备

系统环境 xp+.net2.0+oracle9i

表结构(由于是测试,表结构随便建了一张) XX

字段名

类型

CONFIG

CLOB

1.

 

using System;
using System.Collections;
using System.Collections.Generic;

using UNI.FS.Capability.DAL.Base;

namespace UNI.FS.Capability.DAL.Model
{
    public partial class GatherPoint : BusinessBase<string>
    {
        #region Declarations
 

 


        
    
        
      
        
  private System.String _conFig = null;
        
            /// <summary>
        /// 配置
        /// </summary>
  public virtual System.String  ConFig
        {
            get { return _conFig; }
   set
   {
    OnConFigChanging();
    _conFig = value;
    OnConFigChanged();
   }
        }
  partial void OnConFigChanging();
  partial void OnConFigChanged();
  
         
       
    }
}

 

使用NHibernate的自定义类型,不是太会,幸好网上有高人提供代码,在此想高人致谢。这样我们通过自定义类型来设置正确的OracleType即可。在项目中添加两个类。


 

2.OracleClobField.cs

 

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OracleClient;
using System.Text;

namespace UNI.FS.Capability.DAL.type
{
    public class OracleClobField : PatchForOracleLobField
    {
        public override void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            if (cmd is OracleCommand)
            {
                //CLob、NClob类型的字段,存入中文时参数的OracleDbType必须设置为OracleDbType.Clob
                //否则会变成乱码(Oracle 10g client环境)
                OracleParameter param = cmd.Parameters[index] as OracleParameter;
                if (param != null)
                {
                    param.OracleType = OracleType.Clob;// 关键就这里啦
                    param.IsNullable = true;
                }
            }
            NHibernate.NHibernateUtil.StringClob.NullSafeSet(cmd, value, index);
        }
    }
}

 

3.PatchForOracleLobField.cs

 


using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using NHibernate;
using NHibernate.SqlTypes;
using NHibernate.UserTypes;

namespace UNI.FS.Capability.DAL.type
{
    public abstract class PatchForOracleLobField : IUserType
    {
        public PatchForOracleLobField()
        {
        }

        public bool IsMutable
        {
            get { return true; }
        }
        public System.Type ReturnedType
        {
            get { return typeof(String); }
        }

        public SqlType[] SqlTypes
        {
            get
            {
                return new SqlType[] { NHibernateUtil.String.SqlType };
            }
        }

        public object DeepCopy(object value)
        {
            return value;
        }
        public new bool Equals(object x, object y)
        {
            return x == y;
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }
        public object Assemble(object cached, object owner)
        {
            return DeepCopy(cached);
        }

        public object Disassemble(object value)
        {
            return DeepCopy(value);
        }
        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            return NHibernate.NHibernateUtil.StringClob.NullSafeGet(rs, names[0]);
        }

        public abstract void NullSafeSet(IDbCommand cmd, object value, int index);

        public object Replace(object original, object target, object owner)
        {
            return original;
        }
    }
}

 

 

4.<property name="ConFig" type="UNI.FS.Capability.DAL.type.OracleClobField,UNI.FS.Capability.DAL" column="CONFIG"  />