Свободное сопоставление NHibernate со столбцом идентификатора CHAR (10) SQL Server
Новое в NHibernate и Fluent NHibernate, и я пытаюсь решить проблему производительности в некотором унаследованном коде, вызванную преобразованием CHAR(10)
столбец к NVARCHAR
,
Из SQL Profiler:
exec sp_executesql N'select mytestclas0_.LinkId as LinkId45_,
mytestclas0_.Href as Href45_,
mytestclas0_.LinkActive as LinkActive45_
from MessageLinks mytestclas0_
where mytestclas0_.LinkId=@p0',N'@p0 nvarchar(4000)',@p0=N'BzE2T48HMF'
Вы можете видеть, что ID, поступающий из NHibernate, показан как NVARCHAR
,
Определение таблицы:
CREATE TABLE [dbo].[MyTable](
[ID] [int] NULL,
[Href] [nvarchar](1000) NULL,
[LinkActive] [bit] NOT NULL,
[LinkId] [char](10) NOT NULL
)
Файл класса:
public class MyTestClass {
public MyTestClass() {}
public virtual string LinkId{ get; set; }
public virtual string Href{ get; set; }
public virtual bool LinkActive { get; set; }
}
Файл сопоставления:
public class MyTestClassMapping : ClassMap<MyTestClass> {
public MyTestClassMapping() {
Table("MyTable");
Id(x => x.LinkId).Length(10);
Map(x => x.LinkId);
Map(x => x.Href);
Map(x => x.LinkActive);
}
}
Я пробовал несколько разных вещей с типом данных LinkId и файлом сопоставления, включая эти сопоставления:
Id(x => x.LinkId).CustomSqlType("char(10)");
Id(x => x.LinkId).Length(10).CustomSqlType("char");
Id(x => x.LinkId).CustomSqlType("char");
Я ищу указатель на пример или документацию, которая объясняет, как передать ID, переданный NHibernate в CHAR(10)
,
Заранее благодарю за любую помощь.
3 ответа
Отображение должно быть таким (см. Документацию 5.2.2. Основные типы значений):
Id(x => x.LinkId)
.CustomType("AnsiString")
...
;
Тип NHibernate для char
(не строка Юникода) type="AnsiString"
для картографирования xml. вышеизложенный способ, как это сделать на беглом языке.
Смотрите похожую историю здесь: Производительность NHibernate (Ansi String против Unicode String)
Примечание: мне никогда не удавалось указать длину... всегда она генерируется NHibernate varchar(8000), используя диалект MS SQL 2008...
NHibernate MsSql2000Dialect и следующие версии корректно определяют AnsiString, а также поддерживают длину и т. Д.
Но текущая реализация SqlDriver изменилась в прошлом году, подробности исправления см. На https://nhibernate.jira.com/browse/NH-3036.
Код теперь игнорирует указанную длину и всегда использует значение по умолчанию. По умолчанию для AnsiString и некоторых других - varchar(8000)
RegisterColumnType(DbType.AnsiString, SqlClientDriver.MaxSizeForLengthLimitedAnsiString, "VARCHAR($l)");
код из SqlDriver: настройка по умолчанию:
protected static void SetDefaultParameterSize(IDbDataParameter dbParam, SqlType sqlType)
{
switch (dbParam.DbType)
{
case DbType.AnsiString:
case DbType.AnsiStringFixedLength:
dbParam.Size = MaxSizeForLengthLimitedAnsiString;
break;
Исправлена ошибка:
// Used from SqlServerCeDriver as well
public static void SetVariableLengthParameterSize(IDbDataParameter dbParam, SqlType sqlType)
{
SetDefaultParameterSize(dbParam, sqlType);
// no longer override the defaults using data from SqlType, since LIKE expressions needs larger columns
// https://nhibernate.jira.com/browse/NH-3036
//if (sqlType.LengthDefined && !IsText(dbParam, sqlType) && !IsBlob(dbParam, sqlType))
//{
// dbParam.Size = sqlType.Length;
//}
if (sqlType.PrecisionDefined)
{
dbParam.Precision = sqlType.Precision;
dbParam.Scale = sqlType.Scale;
}
}
Это причина означает, что независимо от того, что вы указываете, это не будет иметь никакого значения для параметров. Можно спорить, если это изменение хорошо или нет, я думаю, что нет;)
Это предположение, так как я использовал CustomSqlType, но не лично с char.
Id(x => x.LinkId).Length(10).CustomSqlType("char(10)");
или вам может потребоваться сбросить длину.
Id(x => x.LinkId).CustomSqlType("char(10)");
Вот симияр: