4

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

这是映射文件的摘录:

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

名称为常规字符串/nvarchar(50),值在DB中设置为ntext

我正在尝试将大量 xml 写入“Value”属性。我每次都会遇到异常:

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

我用谷歌搜索了很多,并尝试了许多不同的映射配置:

<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 数据库中?如果是这样,谁能告诉我怎么做?

非常感谢!

4

7 回答 7

6

好的,非常感谢 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 而不是其他数据库。但是你现在有了!

于 2008-09-25T09:04:22.873 回答
0
<property name="Value" type="string" />
  <column name="Value" sql-type="StringClob" />
</property>

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

于 2008-09-23T12:05:43.657 回答
0

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

于 2008-09-23T12:42:14.240 回答
0

试过:

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

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

恐怕都不起作用......同样的例外 - 它仍然说最大值是4000。

于 2008-09-23T13:13:49.843 回答
0

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

尝试:

<property name='Value' type='StringClob' />
于 2008-10-18T01:02:45.530 回答
0

在我当前的 SQL CE 和 NHibernate 部署中,我使用 4001 的长度。然后 NHibernate 将这些内容生成为 NTEXT 而不是 NVARCHAR。

试试看。

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

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

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

于 2009-04-07T08:53:39.277 回答
0

阅读您的帖子后,此修改使其在我的代码中运行

protected override void InitializeParameter(IDbDataParameter dbParam,string name,SqlType sqlType)
    {
        base.InitializeParameter(dbParam, name, sqlType);

        var stringType = sqlType as StringSqlType;
        if (stringType != null && stringType.LengthDefined && stringType.Length > 4000)
        {
            var parameter = (SqlCeParameter)dbParam;
            parameter.SqlDbType = SqlDbType.NText;
        }

    }
于 2011-09-01T13:23:06.217 回答