[英]Fluent NHibernate mapping to a SQL Server CHAR(10) ID column
New to both NHibernate and Fluent NHibernate and I'm trying to resolve a performance problem in some inherited code caused by a conversion of a CHAR(10)
column to NVARCHAR
. NHibernate和Fluent NHibernate都是新手,我试图解决由于将
CHAR(10)
列转换为NVARCHAR
而导致的某些继承代码中的性能问题。
From SQL Profiler: 从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'
You can see the ID coming in from NHibernate is cast as a NVARCHAR
. 您可以看到来自NHibernate的ID被转换为
NVARCHAR
。
Table definition: 表定义:
CREATE TABLE [dbo].[MyTable](
[ID] [int] NULL,
[Href] [nvarchar](1000) NULL,
[LinkActive] [bit] NOT NULL,
[LinkId] [char](10) NOT NULL
)
The class file: 类文件:
public class MyTestClass {
public MyTestClass() {}
public virtual string LinkId{ get; set; }
public virtual string Href{ get; set; }
public virtual bool LinkActive { get; set; }
}
The mapping file: 映射文件:
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);
}
}
I have tried a number of different things with the datatype of the LinkId and the mapping file, including these mappings: 我用LinkId的数据类型和映射文件尝试了许多不同的东西,包括这些映射:
Id(x => x.LinkId).CustomSqlType("char(10)");
Id(x => x.LinkId).Length(10).CustomSqlType("char");
Id(x => x.LinkId).CustomSqlType("char");
I'm looking for a pointer to an example or documentation that explains how to get the ID passed in by NHibernate cast to a CHAR(10)
. 我正在寻找一个指向示例或文档的指针,该指针解释了如何将NHibernate传入的ID转换为
CHAR(10)
。
Thanks in advance for any help. 在此先感谢您的帮助。
The mapping should be like this (see the documentation 5.2.2. Basic value types ): 映射应该是这样的(参见文档5.2.2。基本值类型 ):
Id(x => x.LinkId)
.CustomType("AnsiString")
...
;
NHibernate type for char
(non unicode string) is type="AnsiString"
for xml mapping. char
(非unicode字符串)的NHibernate类型是xml映射的type="AnsiString"
。 the above is the way how to do that in fluent. 以上是如何以流利的方式做到这一点的方式。
See similar story here: NHibernate Performance (Ansi String vs. Unicode String) 在这里看到类似的故事: NHibernate性能(Ansi字符串与Unicode字符串)
Side Note: I've never managed to specify length ... always it is generated by NHibernate varchar(8000), using MS SQL 2008 dialect... 旁注:我从未设法指定长度...总是由NHibernate varchar(8000)生成,使用MS SQL 2008方言...
NHibernate MsSql2000Dialect and following versions define AnsiString correctly, also supporting length etc. NHibernate MsSql2000Dialect和以下版本正确定义AnsiString,也支持长度等。
But, the current implementation of the SqlDriver got a change last year, see https://nhibernate.jira.com/browse/NH-3036 for details of the fix. 但是,SqlDriver的当前实现去年有所改变,请参阅https://nhibernate.jira.com/browse/NH-3036以获取修复的详细信息。
The code does now ignore the specified length and always uses the default. 代码现在忽略指定的长度并始终使用默认值。 Default for AnsiString and some others is varchar(8000)
AnsiString和其他一些的默认值是varchar(8000)
RegisterColumnType(DbType.AnsiString, SqlClientDriver.MaxSizeForLengthLimitedAnsiString, "VARCHAR($l)");
code from SqlDriver: setting default: 来自SqlDriver的代码:设置默认值:
protected static void SetDefaultParameterSize(IDbDataParameter dbParam, SqlType sqlType)
{
switch (dbParam.DbType)
{
case DbType.AnsiString:
case DbType.AnsiStringFixedLength:
dbParam.Size = MaxSizeForLengthLimitedAnsiString;
break;
Bugfix: 修正:
// 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;
}
}
This of cause means no matter what you specify, it will not matter at all for the parameters. 这个原因意味着无论您指定什么,参数都无关紧要。 One can argue if this change is a good thing or not, I guess it is not ;)
有人可以争辩说,如果这种改变是好事,我想这不是;)
This is a guess, as I've used CustomSqlType, but not personally with char. 这是一个猜测,因为我使用了CustomSqlType,但没有使用char。
Id(x => x.LinkId).Length(10).CustomSqlType("char(10)");
or you may have to drop the Length. 或者你可能不得不放弃长度。
Id(x => x.LinkId).CustomSqlType("char(10)");
Here is a simiar: 这是一个simiar:
Possible to use CustomSqlType with CompositeId? 可以将CustomSqlType与CompositeId一起使用吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.