Question

J'utilise nhibernate pour stocker certains paramètres utilisateur pour une application dans une table SQL Server Compact Edition.

Ceci est un extrait du fichier de mappage:

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

Nom est une chaîne normale / nvarchar (50) et Value est défini comme ntext dans la base de données

.

J'essaie d'écrire une grande quantité de XML dans & "Valeur &"; propriété. Je reçois une exception à chaque fois:

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

Je l'ai consulté assez souvent et j'ai essayé différentes configurations de mappage:

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

C'est un exemple. Les autres configurations incluent & Quot; ntext & Quot; au lieu de & "; StringClob &"; Les configurations qui ne génèrent pas d’exceptions de mappage émettent toujours l’exception de troncature de chaîne.

Est-ce un problème (" fonctionnalité ") avec SQL CE? Est-il possible de mettre plus de 4000 caractères dans une base de données SQL CE avec nhibernate? Si oui, quelqu'un peut-il me dire comment?

Merci beaucoup!

Était-ce utile?

La solution

D'accord, merci beaucoup à Artur pour son cette discussion , voici la solution: Hériter du SqlServerCeDriver avec un nouveau et substituer la méthode 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;
            }

        }
    }
}

Ensuite, utilisez ce pilote au lieu de NHibernate dans votre app.config

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

J'ai vu beaucoup d'autres publications où le même problème existait et je l'ai résolu en changeant l'attribut de type sql en & "StringClob &"; - comme tenté dans ce fil.

Je ne sais pas pourquoi cela ne fonctionnerait pas pour moi, mais je soupçonne que c'est le fait que j'utilise SQL CE et non une autre base de données. Mais voilà!

Autres conseils

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

Je suppose que c'est une petite faute de frappe, puisque vous avez fermé la balise de propriété à deux reprises. En le soulignant, au cas où ce ne serait pas une faute de frappe.

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

Essayé:

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

et

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

Je ne crains rien ni l'un ni l'autre ... Même exception - il est toujours indiqué que la valeur maximale est 4 000.

Pourquoi utilisez-vous la syntaxe de sous-élément?

essayez:

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

Sur mes versions actuelles de SQL CE et de NHibernate, j’utilise une longueur de 4001. NHibernate génère le contenu sous la forme NTEXT au lieu de NVARCHAR.

Essayez ça.

Une autre chose à utiliser avec NHibernate et SQL CE est la suivante:

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

Cela résout d’autres problèmes au moins pour moi.

Après avoir lu votre message, cette modification a fonctionné dans mon code

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

    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top