N-Hibernate在Oracle中使用长字符串会导致错误。

4

我正在使用Oracle作为数据库,Fluent Nhibernate用于映射。

以下是我的对象类:

 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; }
    }

属性 EventScript 的长度可以从 0 到 4000。

在数据库中,我将 EventScript 的列类型设置为 CLOB。

下面是我的映射类:

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");
        }

现在每当EventScript的长度大于2000时,我在将对象保存到数据库时会收到错误提示"ORA-01461: can bind a LONG value only for insert into a LONG column." 请问有人可以帮忙解决吗?
1个回答

6
这是一个已知的问题,涉及到.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)。
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;
        }
    }
}

您需要更新SessionFactory以使用此驱动程序,同时更新任何使用StringClob自定义类型的clob映射。

Map(x => x.EventType).CustomSqlType("Clob").CustomType("StringClob");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接