N-Hibernate中的长字符串与Oracle导致错误 [英] Long strings in N-Hibernate with Oracle cause error
问题描述
下面是我的对象类
public class UserFieldEvent
{
public virtual int Id {get;组; }
public virtual UserFieldBase UserField {get;组; }
public virtual EventType EventType {get;组; }
public virtual string EventScript {get;组; }
}
EventScript的长度可以从0到4000.
在数据库中,我为EventScript创建了一个CLOB类型的列。
下面是我的映射类:
public UserFieldEventMap()
{
表(TBLDS_USERFIELDEVENT);
Id(x => x.Id).GeneratedBy.Sequence(SEQDS_USERFIELDEVENT);
Map(x => x.EventType).CustomType< EventType>();
Map(x => x.EventScript).CustomSqlType(CLOB);
引用(x => x.UserField).Column(USERFIELDBASEID);
$ b现在每当EventScript的长度大于2000时,我都会收到错误ORA -01461:只能绑定LONG值才能插入到LONG列中。同时将对象保存到数据库中。任何人都可以提供帮助。
解决方案这是.NET提供的
System.Data .OracleClient.OracleConnection
驱动程序。修复方法是使用Oracle提供的ODP.net客户端Oracle.DataAccess.Client.OracleConnection
(请参阅: http://nuget.org/packages/odp.net.x86/ )或使用以下解决方法(引用自: http://thebasilet.blogspot.be/2009/07/nhibernate-oracle-clobs.html a>)。
pre $ public $ CustomOracleDriver:OracleClientDriver
{
protected override void InitializeParameter(System.Data .dbbDataParameter dbParam,字符串名称,SqlType sqlType)
{
base.InitializeParameter(dbParam,name,sqlType);
// System.Data.OracleClient.dll驱动程序生成一个ORA-01461异常,因为
//驱动程序错误地推断了正在保存的字符串的列类型,
//尝试强制服务器将LONG值更新为CLOB / NCLOB列类型。
//不正确行为的原因更加模糊,只有满足以下所有条件时才会发生
// //。
// 1.)IDbDataParameter.Value =(字符串,其长度:4000>长度> 2000)
// 2.)IDbDataParameter.DbType = DbType.String
// 3。 )DB列的类型是NCLOB / CLOB
//上面是NHibernate的默认行为.OracleClientDriver
//所以我们使用内建的StringClobSqlType来告诉驱动程序使用NClob Oracle类型
//这对于两个NCLOB / CLOB都没有问题。
//映射文件必须更新为使用StringClob作为属性类型
//请参阅:http://thebasilet.blogspot.be/2009/07/nhibernate-oracle-clobs.html
(if(sqlType is StringClobSqlType))
{
((OracleParameter)dbParam).OracleType = OracleType.NClob;
你需要更新你的
SessionFactory
来使用这个驱动,以及更新你的clob映射来使用StringClob
自定义类型Map(x => x.EventType).CustomSqlType(Clob)。CustomType(StringClob);
I am using oracle as db and fluent Nhibernate for mapping.
Below is my Object Class
public class UserFieldEvent { public virtual int Id { get; set; } public virtual UserFieldBase UserField { get; set; } public virtual EventType EventType { get; set; } public virtual string EventScript { get; set; } }
The length of property EventScript can be from 0 to 4000. In the database I made the column type for EventScript a CLOB.
Below is my mapping Class:
public UserFieldEventMap() { Table("TBLDS_USERFIELDEVENT"); Id(x => x.Id).GeneratedBy.Sequence("SEQDS_USERFIELDEVENT"); Map(x => x.EventType).CustomType<EventType>(); Map(x => x.EventScript).CustomSqlType("CLOB"); References(x => x.UserField).Column("USERFIELDBASEID"); }
Now whenever the length of EventScript is greater than 2000 I get the error "ORA-01461: can bind a LONG value only for insert into a LONG column ." while saving the object into database. Can anyone help on this.
解决方案This is a known issue with the .NET provided
System.Data.OracleClient.OracleConnection
driver. The fix is either to use the Oracle provided ODP.net clientOracle.DataAccess.Client.OracleConnection
(see: http://nuget.org/packages/odp.net.x86/) or use the following workaround (referenced from: http://thebasilet.blogspot.be/2009/07/nhibernate-oracle-clobs.html).public class CustomOracleDriver : OracleClientDriver { protected override void InitializeParameter(System.Data.IDbDataParameter dbParam, string name, SqlType sqlType) { base.InitializeParameter(dbParam, name, sqlType); // System.Data.OracleClient.dll driver generates an ORA-01461 exception because // the driver mistakenly infers the column type of the string being saved, and // tries forcing the server to update a LONG value into a CLOB/NCLOB column type. // The reason for the incorrect behavior is even more obscure and only happens // when all the following conditions are met. // 1.) IDbDataParameter.Value = (string whose length: 4000 > length > 2000 ) // 2.) IDbDataParameter.DbType = DbType.String // 3.) DB Column is of type NCLOB/CLOB // The above is the default behavior for NHibernate.OracleClientDriver // So we use the built-in StringClobSqlType to tell the driver to use the NClob Oracle type // This will work for both NCLOB/CLOBs without issues. // Mapping file must be updated to use StringClob as the property type // See: http://thebasilet.blogspot.be/2009/07/nhibernate-oracle-clobs.html if ((sqlType is StringClobSqlType)) { ((OracleParameter)dbParam).OracleType = OracleType.NClob; } } }
You need to update your
SessionFactory
to use this driver, as well as update any of your clob mappings to useStringClob
custom typeMap(x => x.EventType).CustomSqlType("Clob").CustomType("StringClob");
这篇关于N-Hibernate中的长字符串与Oracle导致错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!