我有一个NHibernate实体,其中包含以下字段:
public virtual decimal ApprovedQuantity { get; set; }
并且该实体的ClassMap包含以下内容:
Map (x => x.ApprovedQuantity).Column("approved_qty").CustomType<decimal>().Precision(7).Scale(2);
SQL Server表定义如下:
CREATE TABLE stock (
project_code NCHAR(30) NOT NULL,
item_code NCHAR(25) NOT NULL,
classification NCHAR(100) NOT NULL,
name NCHAR(30) NOT NULL,
depot_reference NCHAR(12) NOT NULL,
total_qty DECIMAL(7, 2) NOT NULL,
approved_qty DECIMAL(7, 2) NOT NULL,
unapproved_qty DECIMAL(7, 2) NOT NULL,
last_modified SMALLDATETIME,
PRIMARY KEY (project_code, item_code, classification, name, depot_reference)
当我构建NHibernate标准以针对此表运行查询时,获取具有批准数量的所有库存商品&gt; 200(按各种其他字段分组),NHibernate记录的生成的SQL如下所示:
NHibernate: SELECT this_.item_code as y0_, this_.name as y1_, this_.classification as y2_, sum(this_.total_qty) as y3_, sum(this_.approved_qty) as y4_, sum(this_.unapproved_qty) as y5_ FROM stock this_ WHERE this_.project_code = @p0 and ((this_.depot_reference = @p1 or this_.depot_reference = @p2 or this_.depot_reference = @p3)) GROUP BY this_.item_code, this_.name, this_.classification HAVING sum(this_.approved_qty) > @p4 ORDER BY y0_ asc;@p0 = 'MyProject' [Type: AnsiStringFixedLength (8000)], @p1 = '10R' [Type: AnsiStringFixedLength (8000)], @p2 = '16Z' [Type: AnsiStringFixedLength (8000)], @p3 = '17T' [Type: AnsiStringFixedLength (8000)], @p4 = 200 [Type: Currency (8)]
请注意,在这个日志条目的最后,尽管我明确地将ClassMap中的字段映射到'decimal'类型,但@ p4参数被NHibernate声明为'currency'类型。
我不会认为这本身会导致太多问题,但在SQL Server端,它最终会将@ p4参数编译为值'0.02'。我通过在SQL Server端获取查询计划的XML来获得这个:
<ColumnReference Column="@p4" ParameterCompiledValue="($0.0200)"
因此SQL Server基本上最终将我的'200'值视为'0.02',当然查询会返回意外结果。
如果我能让NHibernate将@ p4声明为十进制类型而不是货币类型,我希望这个问题能够得到解决。为什么它似乎忽略了我将此字段显式映射到ClassMap中的“十进制”SQL Server类型的尝试?即使没有显式映射到CustomType,它仍然使用'money'SQL Server类型。
感谢。
答案 0 :(得分:0)
尝试更改
CustomType
到
CustomSqlType
答案 1 :(得分:0)
取消对CustomType<T>()
的通话。 NHibernate应该能够从映射属性的类型中解析它。
答案 2 :(得分:0)
我已将实体的属性类型更改为“Double”而不是“Decimal”:
public virtual Double ApprovedQuantity { get; set; }
并且没有进行任何CustomType / CustomSqlType()调用:
Map (x => x.ApprovedQuantity).Column("approved_qty");
现在根据NHibernate日志记录,用于查询的参数类型正确:
NHibernate: SELECT this_.item_code as y0_, this_.name as y1_,....@p4 = 600 [Type: Double (8)]
并且查询按预期运行。
我们没有在这张表中保存极其精确的数量(最多只有1位小数),所以即使表格列的类型为DECIMAL(我无法控制,它不是我的),我也不会失去任何精确度。模式)。
谢谢大家。