Проблема усечения NHibernate nvarchar / ntext - PullRequest
4 голосов
/ 23 сентября 2008

Я использую nhibernate для хранения некоторых пользовательских настроек приложения в таблице SQL Server Compact Edition.

Это фрагмент файла сопоставления:

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

Имя представляет собой обычную строку / nvarchar (50), а значение устанавливается как ntext в БД

Я пытаюсь записать большое количество xml в свойство "Value". Я получаю исключение каждый раз:

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

Я немного погуглил и попробовал несколько разных конфигураций сопоставления:

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

Это один пример. Другие конфигурации включают «ntext» вместо «StringClob». Те конфигурации, которые не генерируют исключения сопоставления, по-прежнему генерируют исключение усечения строки.

Это проблема («особенность») в SQL CE? Можно ли поместить более 4000 символов в базу данных SQL CE с помощью nhibernate? Если да, может кто-нибудь сказать мне, как?

Большое спасибо!

Ответы [ 7 ]

6 голосов
/ 25 сентября 2008

Хорошо, большое спасибо Артуру в этой теме , вот решение: Унаследуйте от 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;
            }

        }
    }
}

Затем используйте этот драйвер вместо NHibernate в вашем app.config

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

Я видел много других постов, где люди сталкивались с этой проблемой, и решил ее, просто изменив атрибут sql-type на "StringClob" - как попыталось сделать в этой теме.

Я не уверен, почему это не будет работать для меня, но я подозреваю, что это тот факт, что я использую SQL CE, а не какую-то другую БД. Но вот оно!

0 голосов
/ 01 сентября 2011

После прочтения вашего поста эта модификация заработала в моем коде

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

    }
0 голосов
/ 07 апреля 2009

В моем текущем деплиоменте SQL CE и NHibernate я использую длину 4001. Затем NHibernate генерирует материал как NTEXT вместо NVARCHAR.

Попробуйте это.

Еще одна вещь, которую можно использовать с NHibernate и SQL CE, это:

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

Это решает некоторые другие проблемы для меня, по крайней мере.

0 голосов
/ 18 октября 2008

Почему вы используете синтаксис подэлемента?

попробовать:

<property name='Value' type='StringClob' />
0 голосов
/ 23 сентября 2008

Пробовал:

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

и

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

Боюсь, ничего не сработало ... То же самое исключение - оно по-прежнему говорит, что максимальное значение равно 4000.

0 голосов
/ 23 сентября 2008

Попробуйте <property name="Value" type="string" length="4001" />

0 голосов
/ 23 сентября 2008
<property name="Value" type="string" />
  <column name="Value" sql-type="StringClob" />
</property>

Я предполагаю, что это небольшая опечатка, так как вы дважды закрыли тег свойства. Просто указываю на это, на случай, если это не опечатка.

...