Свободное сопоставление 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)");

Вот симияр:

Возможно ли использовать CustomSqlType с CompositeId?

Другие вопросы по тегам