4

NHibernate と Fluent NHibernate の両方に不慣れで、CHAR(10)列をNVARCHAR.

SQL プロファイラーから:

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'

NHibernate からの ID が としてキャストされていることがわかります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");

NHibernate によって渡された ID を にキャストする方法を説明する例またはドキュメントへのポインターを探していますCHAR(10)

助けてくれてありがとう。

4

3 に答える 3

5

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

これは、何を指定しても、パラメーターにはまったく問題がないことを意味します。この変更が良いことかどうかは議論の余地がありますが、私はそうではないと思います ;)

于 2013-09-28T16:48:49.443 に答える
5

マッピングは次のようになります (ドキュメント5.2.2. Basic value typesを参照):

Id(x => x.LinkId)      
  .CustomType("AnsiString")
  ...
  ;

char(非 Unicode 文字列)の NHibernate 型はtype="AnsiString"、xml マッピング用です。上記は流暢にそれを行う方法です。

ここで同様の話を参照してください: NHibernate のパフォーマンス (Ansi 文字列と Unicode 文字列)

補足:長さを指定することはできませんでした...常に、MS SQL 2008 方言を使用して、NHibernate varchar(8000) によって生成されます...

于 2013-09-28T14:10:57.270 に答える