2016-03-02 39 views
0

「錢」 I型有以下領域的NHibernate的實體:NHibernate的/ FluentNHibernate堅持使用十進制參數

public virtual decimal ApprovedQuantity { get; set; } 

,併爲這個實體類映射包含以下內容:

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標準IA來對這個表運行一個查詢,以獲得經批准的數量所有庫存物品> 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服務器端獲取查詢計劃的XML獲得這樣的:

<ColumnReference Column="@p4" ParameterCompiledValue="($0.0200)" 

所以SQL服務器基本上結束了治療我的「200」值「0.02」,當然還有查詢返回意外的結果。

如果我可以讓NHibernate將@ p4聲明爲十進制類型,而不是貨幣類型,我希望這個問題將得到解決。爲什麼它似乎無視我試圖將此字段顯式映射到ClassMap中的「十進制」SQL Server類型?即使沒有顯式映射到CustomType,它仍然使用'money'SQL Server類型。

謝謝。

+1

從你自己的答案看來,你似乎已經找到了適合自己的解決方案。然而,這種行爲感覺很奇怪 - 如果你可以做兩件事情會很有趣:1)從FluentNHibernate獲得生成的XML映射,以便我們可以看到層之間發生了什麼,以及2)請求NHibernate生成數據庫模式一個字符串)來查看它想要用於列的類型(查看問題是否隻影響參數的類型)。都沒有任何CustomType <>或CustomSqlType()。 –

+0

我認爲這是一個有用的想法,我會看看如果我可以去看看它。 – Jimidy

回答

0

嘗試改變

CustomType

CustomSqlType

+1

另請參見:aeliusd在這裏的答案:http://stackoverflow.com/questions/2033630/datetime-precision-in-nhibernate-and-support-for-datetime2-in-nhibernate-schemee – granadaCoder

+0

CustomSqlType(「decimal」 )也不起作用。看起來我不得不使用公約或類似的方式來覆蓋行爲,正如您鏈接到的那個問題中所建議的那樣。謝謝。 – Jimidy

+0

您是否嘗試過「內聯」CustomType和CustomSqlType(同時)?是的,如果你不得不訴諸習俗......那太臭了。 – granadaCoder

0

刪除調用CustomType<T>()。 NHibernate應該能夠從映射屬性的類型中解析它。

+0

不幸的是,它仍然嘗試使用「金錢」SQL Server類型。這就是爲什麼我試圖明確地將它映射到CustomType 和CustomType ,在任何情況下都無濟於事。 – Jimidy

0

我已經改變了實體的屬性類型,以 '雙師型' 而不是 '十進制':

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_,[email protected] = 600 [Type: Double (8)] 

和查詢功能如預期。

我們在這張表裏並沒有保持非常精確的數量(最好是1個小數位),所以即使表格列的類型是DECIMAL,也不會失去任何精度(我無法控制,它不是我的模式)。

謝謝大家。