【问题标题】:Mapping clobs using Fluent NHibernate, Oracle 10g and OracleClientConfiguration.Oracle10使用 Fluent NHibernate、Oracle 10g 和 OracleClientConfiguration.Oracle10 映射 clob
【发布时间】:2011-11-10 16:45:49
【问题描述】:

我一直在尝试使用 Fluent NHibernate 1.2.0.712 针对 Oracle 10g 映射 clob 字段。我正在使用 System.Data 提供程序,因为它默认可用,并且由于以前的客户端问题而试图避免添加对 ODP.Net 的引用。

但是,当我尝试插入具有映射 clob 属性的实体时,出现错误:

ORA-01461: 只能绑定 LONG 值以插入 LONG 列

我尝试通过使用以下约定来解决此问题,并使用 [StringLength(4000)] 装饰适当的属性:

public class StringLengthConvention : AttributePropertyConvention<StringLengthAttribute>
{
    protected override void Apply(StringLengthAttribute attribute, IPropertyInstance instance)
    {
        instance.Length(attribute.MaximumLength);
    }
}

这不起作用。

然后我使用“TEXT”、“CLOB”和“clob”值尝试了以下操作。都没有用:

    public class plaparteMappingOverride : IAutoMappingOverride<plaparte>
    {
        public void Override(AutoMapping<plaparte> mapping)
        {
           Map(x => x.disposiciones).CustomSqlTypeIs("TEXT");
        } 
    }

除了将 ODP 添加为提供程序之外,是否有人对此修复有进一步的建议?

【问题讨论】:

  • 我不是 Microsoft 提供商,但使用 ODP.NET,您不需要任何特殊的 CLOB,它们只是映射为普通字符串(有一个例外,它尝试将空字符串插入为null 而不是空的 clob)。您的 plaparte.disposiciones 属性是字符串吗?

标签: nhibernate fluent-nhibernate oracle10g fluent-nhibernate-mapping


【解决方案1】:

供将来参考:this post 完美描述了导致此错误的原因以及解决方法。

ORA-01461: 只能绑定 LONG 值以插入到 LONG 列中

这个错误不是很有帮助,而且很可能会导致 在有关 Oracle 补丁等的主题中。实际上这是一个 微软 oracle 客户端驱动程序的错误。司机误会 推断正在保存的字符串的列类型,并尝试强制 服务器将 LONG 值更新为 CLOB/NCLOB 列类型。这 不正确行为的原因更加模糊,只有 当满足以下所有条件时发生。

  1. 当我们设置 IDbDataParameter.Value = (字符串长度为 : 4000 > length > 2000 )
  2. 当我们设置 IDbDataParameter.DbType = DbType.String
  3. 当 DB 列是 NCLOB/CLOB 类型时

不幸的是,NHibernate 2.0 的默认行为是完全按照 上面,使它更有可能遇到这个丑陋的错误 使用 nhibernate 和 oracle。

博文中提供的解决方案:自定义 NHibernate Oracle 驱动程序:

/// <summary>
/// Initializes the parameter.
/// </summary>
/// <param name="dbParam">The db param.
/// <param name="name">The name.
/// <param name="sqlType">Type of the SQL.
protected override void InitializeParameter(System.Data.IDbDataParameter dbParam, string name, global::NHibernate.SqlTypes.SqlType sqlType)
{
    base.InitializeParameter(dbParam, name, sqlType);

    //System.Data.OracleClient.dll driver generates an exception
    //we set the IDbDataParameter.Value = (string whose length: 4000 > length > 2000 )
    //when we set the IDbDataParameter.DbType = DbType.String
    //when 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 will need to be update to use StringClob as the property type
    if ((sqlType is StringClobSqlType))
    {
        ((OracleParameter)dbParam).OracleType = OracleType.NClob;
    }
}

【讨论】:

  • 虽然这在理论上可以回答这个问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。
猜你喜欢
  • 2011-04-10
  • 2012-10-19
  • 1970-01-01
  • 2011-06-18
  • 2010-12-09
  • 2012-04-03
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多