为何NHibernate忽略列类型映射使用NVARCHAR而非VARCHAR?
问题原因
- 映射配置的类型不匹配:你在hbm.xml中将
Object_id属性的type设为了String,该类型对应NHibernate内置的StringType,默认绑定SQL Server的Unicode字符类型nvarchar,优先级高于你配置的sql-type="varchar"。即使你指定了sql-type,参数生成阶段仍会优先按属性的type定义推断参数类型。 - Criteria属性绑定失败:如果你在
Expression.Eq中填写的属性名和映射文件中property节点的name属性拼写、大小写不一致,NHibernate无法关联到对应的映射元数据,也就无法读取你配置的length和sql-type,会默认将.NET的string类型参数映射为nvarchar(4000)。 - 版本特定行为:NHibernate 4.1.x版本存在默认字符串参数推断逻辑,对未显式指定类型且未成功绑定映射的字符串参数,会直接使用
nvarchar(4000)作为参数类型。
解决方法
- 方案1:修正映射配置
将hbm.xml中对应属性的type从String改为AnsiString,AnsiString类型对应非Unicode的varchar类型,配置修改后NHibernate会自动读取你设置的length="40",生成varchar(40)类型的参数:
<property name="Object_id" type="AnsiString"> <column name="object_id" not-null="false" length="40" sql-type="varchar" /> </property>
- 方案2:查询时显式指定参数类型
不需要修改映射的前提下,可以在Criteria查询中显式指定参数类型为AnsiString,强制生成varchar类型参数:
List<Dag> result = session.CreateCriteria<Dag>() .Add(Expression.Eq("Object_id", pObjectId).Type(NHibernateUtil.AnsiString)) .List<Dag>().ToList();
- 方案3:核对属性名
确认Expression.Eq中填写的属性名和映射文件中property节点的name完全一致,包括大小写,确保NHibernate可以正常绑定映射元数据。
内容的提问来源于stack exchange,提问作者GrumpyRodriguez
相关产品推荐
相关产品推荐

