2016-04-26 59 views
0

我正在使用NHibernate和流利NHibernate進行映射的.NET Web API應用程序。是否有可能從標量函數的結果中分配默認值

我有一個名爲標量函數「next_photo_id()」產生像 Sharding & IDs at Instagram

Int64的數量,但我不能指定標量函數MySQL中的默認值ID列。我試過了,我得到了錯誤。

ALTER TABLE `photos` 
    CHANGE COLUMN `id` `id` BIGINT(20) NOT NULL DEFAULT next_photo_id() FIRST ; 

所以我試着從應用程序端使用fluentNhibernate分配Id。

我的照片表的類映射是

public class PhotoMap : ClassMap<Photo> 
{ 
    public PhotoMap() 
    { 
     Table("photos"); 


     Id(m => m.Id).Column("id").Access.Property().Default("next_photo_id()"); 

     Map(m => m.Caption).Column("caption"); 
    } 
} 

照片表插入查詢必須是,

Insert Into photos (id,caption) values (next_photo_id(),"test") 

但我不能這樣做。無論如何去做?

回答

1

在映射中定義默認值僅適用於DDL。所以基本上,你剛剛告訴NHibernate嘗試定義默認的SQL約束,以防你要求它爲你生成數據庫模式。 (這將與您嘗試直接在SQL中定義的那個相同)。

對於您的情況,您需要定義自定義插入查詢。我知道如何使用的hbm.xml映射做到這一點,它記錄here,它會是這樣的:

<class name="PhotoMap" table="photos"> 
    ... 

    <sql-insert>insert into photos (caption, id) 
     values (?, 
     case when ? is null then next_photo_id() else next_photo_id() end) 
    </sql-insert> 
</class> 

如記錄,你應該首先確定以何種順序NHibernate的發送其參數,並堅持這一順序。此外,NHibernate會期望id的位置參數,如果沒有它,將會失敗。所以我用case解決它。您可以通過使用存儲過程接受所有參數來更加乾淨地處理這個問題,並且哪一個主體會忽略id之一。

對於翻譯這到流利NHibernate,我不知道,我不使用它。

您現在仍然有一個重大障礙需要克服:您應該使用什麼發電機作爲您的ID字段?我沒有看到任何合適的東西。你可能對NHibernate說謊,並告訴它類似assigned,但它不會爲你檢索在db端生成的id。你必須清除會話,並查詢你新添加的照片,如果你有一些自然ID找到它...

否則,你必須實施custom id generator支持你的情況。它應該是靠近身份的東西。但要小心,這一個,as documented,導致sql-insert被忽略。實施自定義生成器時可能會遇到同樣的問題。

如果您id是一個簡單的屬性,而不是實體ID,你可以簡單地告訴NHibernate的是generated

<property name="Id" generated="insert" /> 

但對於ID,如上所述,這是方式較爲複雜,只要我知道。

數據庫端

您的默認值應該可以在db中執行。與SQL Server,定義默認會像一個正確的方法:

alter table photos add constraint DefPhotosId default (dbo.next_photo_id()) for Id 

如果在試圖定義默認出現你的錯誤你應該打開一個MySQL的問題。

但無論如何,你仍然會在NHibernate端有id生成器的麻煩。

相關問題