NHibernate / FluentNHibernate坚持使用'money'类型作为十进制参数

时间:2016-03-02 15:35:12

标签: c# sql-server nhibernate fluent-nhibernate

我有一个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类型。

感谢。

3 个答案:

答案 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(我无法控制,它不是我的),我也不会失去任何精确度。模式)。

谢谢大家。