Fluent NHibernate映射到SQL Server CHAR(10) ID列
本文关键字:ID CHAR Server NHibernate 映射 SQL Fluent | 更新日期: 2023-09-27 18:33:16
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);
}
}
我已经尝试了许多不同的东西,包括这些映射:
Id(x => x.LinkId).CustomSqlType("char(10)");
Id(x => x.LinkId).Length(10).CustomSqlType("char");
Id(x => x.LinkId).CustomSqlType("char");
我正在寻找一个指向示例或文档的指针,该示例或文档解释了如何将 NHibernate 转换为CHAR(10)
的 ID 。
提前感谢任何帮助。
映射应该是这样的(请参阅文档 5.2.2。基本值类型):
Id(x => x.LinkId)
.CustomType("AnsiString")
...
;
char
(非 unicode 字符串)的 NHibernate 类型对于 XML 映射type="AnsiString"
。 以上是如何流利地做到这一点的方法。
在这里查看类似的故事:NHibernate Performance (Ansi String vs. 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,但不是个人使用字符。
Id(x => x.LinkId).Length(10).CustomSqlType("char(10)");
或者您可能不得不删除长度。
Id(x => x.LinkId).CustomSqlType("char(10)");
这是一个类比:
可以将 CustomSqlType 与 CompositeId 一起使用吗?