NHibernate nvarchar / ntext截断问题

时间:2020-03-06 14:35:35  来源:igfitidea点击:

我正在使用nhibernate在SQL Server Compact Edition表中存储应用程序的一些用户设置。

这是映射文件的摘录:

<property name="Name" type="string" />
<property name="Value" type="string" />

名称是常规字符串/ nvarchar(50),并且在数据库中将值设置为ntext

我正在尝试将大量xml写入"值"属性。每次我都会得到一个例外:

@p1 : String truncation: max=4000, len=35287, value='<lots of xml..../>'

我已经在Google上搜索了很多,并尝试了许多不同的映射配置:

<property name="Name" type="string" />
<property name="Value" type="string" >
  <column name="Value" sql-type="StringClob" />
</property>

那是一个例子。其他配置包括" ntext"而不是" StringClob"。那些不引发映射异常的配置仍会引发字符串截断异常。

这是SQL CE的问题("功能")吗?使用nhibernate是否可以将4000个以上的字符放入SQL CE数据库中?如果是这样,谁能告诉我如何?

非常感谢!

解决方案

<property name="Value" type="string" />
  <column name="Value" sql-type="StringClob" />
</property>

我假设这是一个小错字,因为我们已经关闭了两次属性标签。只是指出这一点,以防万一不是拼写错误。

尝试&lt;property name =" Value" type =" string" length =" 4001" />

尝试过:

<property name="Value" type="string" length="4001" />

<property name="Value" type="string" >
  <column name="Value" sql-type="StringClob" length="5000"/>
</property>

恐怕都没用...同样的例外,它仍然说最大值为4000。

好的,非常感谢Artur在此主题中的解决方案:
从SqlServerCeDriver继承一个新的,并重写InitializeParamter方法:

using System.Data;
using System.Data.SqlServerCe;
using NHibernate.Driver;
using NHibernate.SqlTypes;

namespace MySqlServerCeDriverNamespace
{
    /// <summary>
    /// Overridden Nhibernate SQL CE Driver,
    /// so that ntext fields are not truncated at 4000 characters
    /// </summary>
    public class MySqlServerCeDriver : SqlServerCeDriver
    {
        protected override void InitializeParameter(
            IDbDataParameter dbParam,
            string name,
            SqlType sqlType)
        {
            base.InitializeParameter(dbParam, name, sqlType);

            if (sqlType is StringClobSqlType)
            {
                var parameter = (SqlCeParameter)dbParam;
                parameter.SqlDbType = SqlDbType.NText;
            }

        }
    }
}

然后,在app.config中使用此驱动程序而不是NHibernate的驱动程序

<nhibernateDriver>MySqlServerCeDriverNamespace.MySqlServerCeDriver , MySqlServerCeDriverNamespace</nhibernateDriver>

我看到很多其他人遇到此问题的帖子,并通过在此线程中尝试将sql-type属性更改为" StringClob"来解决。

我不确定为什么它对我不起作用,但是我怀疑这是我使用SQL CE而不是其他一些DB的事实。但是你现在有了!

为什么要使用子元素语法?

尝试:

<property name='Value' type='StringClob' />

在我目前对SQL CE和NHibernate的部署中,我使用了4001的长度。然后NHibernate将其生成为NTEXT而不是NVARCHAR。

试试看

与NHibernate和SQL CE一起使用的另一件事是:

<session-factory>
  ...
  <property name="connection.release_mode">on_close</property>
</session-factory>

这至少为我解决了其他一些问题。