NHibernate nvarchar/ntext截断问题

NHibernate nvarchar/ntext截断问题,nhibernate,sql-server-ce,truncate,ntext,Nhibernate,Sql Server Ce,Truncate,Ntext,我正在使用nhibernate将应用程序的一些用户设置存储在SQL Server Compact Edition表中 这是映射文件的摘录: <property name="Name" type="string" /> <property name="Value" type="string" /> Name是一个常规字符串/nvarchar(50),值在数据库中设置为ntext 我正在尝试向“Value”属性写入大量xml。每次我都会遇到一个异常: @p1 : Str

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

这是映射文件的摘录:

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

Name是一个常规字符串/nvarchar(50),值在数据库中设置为ntext

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

@p1 : String truncation: max=4000, len=35287, value='<lots of xml..../>'
@p1:String截断:max=4000,len=35287,value=''
我在谷歌上搜索了不少,并尝试了许多不同的映射配置:

<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>
我假设这是一个小的输入错误,因为您已经关闭了属性标签两次。请指出这一点,以防它不是打字错误。

尝试
尝试:

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



恐怕两个都没用。。。同样的例外-它仍然说最大值是4000。

好的,非常感谢Artur in,这里是解决方案: 使用新方法从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;
            }

        }
    }
}
使用系统数据;
使用System.Data.SqlServerCe;
使用NHibernate.Driver;
使用NHibernate.SqlTypes;
命名空间MySqlServerCeDriverNamespace
{
/// 
///重写的Nhibernate SQL CE驱动程序,
///因此,ntext字段不会被截断为4000个字符
/// 
公共类MySqlServerCeDriver:SqlServerCeDriver
{
受保护的覆盖无效初始化参数(
IDbDataParameter dbParam,
字符串名,
SqlType(SqlType)
{
InitializeParameter(dbParam,name,sqlType);
if(sqlType为StringClobSqlType)
{
var参数=(SqlCeParameter)dbParam;
parameter.SqlDbType=SqlDbType.NText;
}
}
}
}
然后,在app.config中使用此驱动程序而不是NHibernate

<nhibernateDriver>MySqlServerCeDriverNamespace.MySqlServerCeDriver , MySqlServerCeDriverNamespace</nhibernateDriver>
MySqlServerCeDriverNamespace.MySqlServerCeDriver,MySqlServerCeDriverNamespace
我看到很多其他帖子都有这个问题,并通过将sql类型属性更改为“StringClob”解决了这个问题,就像在这个帖子中尝试的那样


我不确定为什么它对我不起作用,但我怀疑这是因为我使用的是SQL CE而不是其他数据库。但是,你有它

为什么要使用子元素语法

尝试:


在我目前的SQL CE和NHibernate部门,我使用的长度是4001。然后NHibernate将生成内容作为NTEXT而不是NVARCHAR

试试看

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

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

...
闭上

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

在阅读了你的文章后,这个修改在我的代码中起到了作用

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;
        }

    }

为什么我不能接受我自己的帖子作为答案?这确实解决了问题,毕竟…我认为这应该纳入主干。我创建了一个JIRA问题来实现这一点:
<session-factory>
  ...
  <property name="connection.release_mode">on_close</property>
</session-factory>
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;
        }

    }