最近利用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" />