NHibernate nvarchar/ntext截断问题
我正在使用nhibernate将应用程序的一些用户设置存储在SQL Server Compact Edition表中 这是映射文件的摘录: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
<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;
}
}