【问题标题】:Long strings in N-Hibernate with Oracle cause errorN-Hibernate 与 Oracle 中的长字符串导致错误
【发布时间】:2012-02-02 23:49:36
【问题描述】:

我正在使用 oracle 作为数据库,并使用流利的 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 ”。同时将对象保存到数据库中。任何人都可以帮助解决这个问题。

【问题讨论】:

    标签: c# oracle nhibernate fluent-nhibernate


    【解决方案1】:

    这是 .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 以使用此驱动程序,并更新您的任何 clob 映射以使用 StringClob 自定义类型

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

    【讨论】:

      猜你喜欢
      • 2016-05-18
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多