繁体   English   中英

Fluent NHibernate映射到SQL Server CHAR(10)ID列

[英]Fluent NHibernate mapping to a SQL Server CHAR(10) ID column

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)

在此先感谢您的帮助。

映射应该是这样的(参见文档5.2.2。基本值类型 ):

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

char (非unicode字符串)的NHibernate类型是xml映射的type="AnsiString" 以上是如何以流利的方式做到这一点的方式。

在这里看到类似的故事: NHibernate性能(Ansi字符串与Unicode字符串)

旁注:我从未设法指定长度...总是由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)");

这是一个simiar:

可以将CustomSqlType与CompositeId一起使用吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM