Причина, по которой это поведение изменилось с 2.x на 3.0.0, была вызвана фиксацией кода на NHibernate.Driver.SqlClientDriver
, которая фактически включила некоторые из режимов включения конфигурации prepare_sql
в порядке решить проблему с кэшированием планов запросов .
Свойство C # string
, сопоставленное столбцу, для которого нет другого type
, указанного в его сопоставлении, будет обработано как NHibernate.SqlTypes.StringSqlType
и получит ограничение в 4000 символов драйвером:
С NHibernate.SqlTypes.StringSqlType
:
/// <remarks>
/// This can store the length of the string that the <see cref="IDbDataParameter"/> can hold.
/// If no value is provided for the length then the <c>Driver</c> is responsible for
/// setting the properties on the <see cref="IDbDataParameter"/> correctly.
/// </remarks>
Итак, вы можете видеть, что приведенный ниже код драйвера (NHibernate.Driver.SqlClientDriver
) отображает свойство string
по умолчанию на длину 4000 символов.
/* SNIP */
private const int MaxAnsiStringSize = 8000;
private const int MaxBinarySize = MaxAnsiStringSize;
private const int MaxStringSize = MaxAnsiStringSize / 2;
private const int MaxBinaryBlobSize = int.MaxValue;
private const int MaxStringClobSize = MaxBinaryBlobSize / 2;
/* SNIP */
private static void SetDefaultParameterSize(IDbDataParameter dbParam, SqlType sqlType)
{
switch (dbParam.DbType)
{
/* SNIP */
case DbType.String:
case DbType.StringFixedLength:
dbParam.Size = IsText(dbParam, sqlType) ? MaxStringClobSize : MaxStringSize;
break;
/* SNIP */
}
}
Для конфигураций с prepare_sql
, установленным на false
, NH 3.0.0 теперь вводит метод SetDefaultParameterSize
в игру, где он не был до
Как вы заметили, вы можете использовать встроенную поддержку NH-3.0.0 для SQL Server XML
тип данных (благодаря NH-866), например:
<property name="Data" type="xml" not-null="true" />
или более явно, но эквивалентно:
<property name="Data" type="XmlDoc" not-null="true">
<column name="DATA" sql-type="XmlSql" />
</property>
Но при использовании NHibernate.Type.XmlDocType
ожидается, что тип свойства будет иметь тип C # XmlDocument
- что приведет к исключению приведения.
Вы можете сделать исправление XmlDocument.InnerXml
, как вы упомянули, но это много ненужного преобразования из строки в документ и обратно. Я использовал следующее отображение, чтобы сохранить свойство домена в виде строки:
<property name="Data" type="StringClob" not-null="true">
<column name="DATA" sql-type="XmlSql" />
</property>
Использование NHibernate.Type.StringClobType
вернет true для вызова IsText(dbParam, sqlType)
в приведенном выше фрагменте драйвера, давая максимальную длину символа int.MaxValue / 2
- что-то вроде 2 ГБ строковых данных.