使用 Fluent NHibernate、Oracle 10g 和 OracleClientConfiguration.Oracle10 映射 clob

发布于 2024-12-15 02:36:16 字数 936 浏览 2 评论 0原文

我一直在尝试使用 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 作为提供程序之外,还有人对此修复有进一步的建议吗?

I've been trying to map a clob field using Fluent NHibernate 1.2.0.712 against Oracle 10g. I'm using System.Data provider as it's available by default and was trying to avoid adding reference to ODP.Net due to previous client issues.

However, when I try to insert entities with mapped clob properties, I get the error:

ORA-01461: can bind a LONG value only for insert into a LONG column

I've tried to fix this by using the below convention, and decorating the appropriate property with [StringLength(4000)]:

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

This didn't work.

Then I tried the below using "TEXT", "CLOB" and "clob" values. Neither worked:

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

Does anyone have further suggestions for this fix other than adding ODP as the provider?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

世俗缘 2024-12-22 02:36:16

供将来参考:这篇文章完美地描述了导致此错误的原因以及你如何解决它。

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

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

  1. 当我们设置 IDbDataParameter.Value = (长度为: 4000 > length > 2000 的字符串)
  2. 当我们设置 IDbDataParameter.DbType = DbType.String
  3. 当数据库列的类型为 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;
    }
}

For future reference: this post perfectly describes what causes this error and how you can solve it.

ORA-01461: can bind a LONG value only for insert into a LONG column

This error is not very helpful and goggling it will most likely result
in topics regarding oracle patches and the like. In reality this is a
bug with the microsoft oracle client driver. 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. when we set the IDbDataParameter.Value = (string whose length is : 4000 > length > 2000 )
  2. when we set the IDbDataParameter.DbType = DbType.String
  3. when DB Column is of type NCLOB/CLOB

Unfortunately NHibernate 2.0's default behavior is to do exactly the
above, making it quite more likely to run into this ugly bug when
using nhibernate and oracle.

Solution offered in the blog post: a custom NHibernate Oracle Driver:

/// <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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文