使用 Oracle 的 N-Hibernate 中的长字符串导致错误 [英] Long strings in N-Hibernate with Oracle cause error

查看:11
本文介绍了使用 Oracle 的 N-Hibernate 中的长字符串导致错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 oracle 作为数据库和流畅的 Nhibernate 进行映射.

I am using oracle as db and fluent Nhibernate for mapping.

下面是我的项目等级

 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.

The length of property EventScript can be from 0 to 4000. In the database I made the column type for EventScript a 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 ".同时将对象保存到数据库中.任何人都可以提供帮助.

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.

推荐答案

这是 .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-clos.html).>

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 client Oracle.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;
        }
    }
}

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

You need to update your SessionFactory to use this driver, as well as update any of your clob mappings to use StringClob custom type

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

这篇关于使用 Oracle 的 N-Hibernate 中的长字符串导致错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆