2008-09-23 96 views
4

我正在使用nhibernate在SQL Server Compact Edition表中存储应用程序的某些用户设置。NHibernate nvarchar/ntext截断问题

这是摘录映射文件:

<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..../>' 

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

非常感谢!

回答

6

好的,非常感谢Artur在this thread,以下是解决方案: 继承一个新的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而不是其他数据库。但是你现在有了!

+0

工作为什么我不能接受我自己的岗位作为答案?这确实解决了这个问题,毕竟... – Reiste 2008-09-25 09:09:27

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

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

0

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

0

尝试:

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

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

但是都没有成功,我怕...同样的例外 - 它仍然表示,最大值为4000。

0

为什么使用子元素语法?

尝试:

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

在我当前的SQL CE和NHibernate我用的是4001的长度的deplyoment。然后NHibernate生成的东西作为NTEXT而不是NVARCHAR。

试试看。

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

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

这解决了一些问题,我ATLEAST。

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

    }