Domanda

Sto usando nhibernate per memorizzare alcune impostazioni utente per un'applicazione in un database di SQL Server Compact Edition tabella.

Questo è un estratto del file di mapping:

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

Il nome è una stringa regolare/nvarchar(50), e il Valore è impostato come tipo di dati ntext nel DB

Sto cercando di scrivere una grande quantità di xml per il "Valore" di proprietà.Ottengo un'eccezione ogni volta che:

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

Ho googlato un bel po', e provato un certo numero di diversi mappatura configurazioni:

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

Questo è un esempio.Altre configurazioni includono "tipo di dati ntext" invece di "StringClob".Quelle configurazioni che non passi la mappatura eccezioni ancora lanciare la stringa di troncamento eccezione.

Questo è un problema ("funzione") con SQL CE?È possibile inserire più di 4000 caratteri in un database di SQL CE con nhibernate?Se è così, qualcuno può dirmi come?

Molte grazie!

È stato utile?

Soluzione

Ok, molte grazie per Artur in questo thread, ecco la soluzione:Ereditano dalla SqlServerCeDriver con uno nuovo, e ignorare il InitializeParamter metodo:

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

        }
    }
}

Quindi, utilizzare questo driver invece di NHibernate nella tua app.config

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

Ho visto un sacco di altri posti dove la gente ha questo problema e risolto da solo di cambiare il sql-tipo di attributo di "StringClob" - come ha tentato in questo thread.

Non so perché non funziona per me, ma ho il sospetto che sia il fatto che sto usando SQL CE e non di qualche altro DB.Ma, non c'è l'ho!

Altri suggerimenti

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

Suppongo che questo sia un piccolo errore di battitura, poiché hai chiuso il tag proprietà due volte. Basta sottolineare questo, nel caso in cui non fosse un refuso.

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

Hai provato:

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

e

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

Né ha funzionato, temo ... Stessa eccezione - dice ancora che il valore massimo è 4000.

Perché stai usando la sintassi dell'elemento secondario?

Prova:

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

Nel mio attuale deplyoment di SQL CE e NHibernate utilizzo una lunghezza di 4001. Quindi NHibernate genera le cose come NTEXT anziché NVARCHAR.

Prova.

Un'altra cosa da usare con NHibernate e SQL CE è:

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

Questo risolve alcuni altri problemi per me almeno.

Dopo aver letto il tuo post questa modifica l'ha fatto funzionare nel mio codice

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

    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top