2016-04-26 15 views
0

マッピングにNHibernateとFluent NHibernateを使用する.NET Web APIアプリケーションで作業しています。スカラー関数の結果からIdにデフォルト値を割り当てることは可能です

私は名前のスカラー関数持た「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の場合のみです。基本的に、あなたはあなたにdbスキーマを生成するように要求した場合に、デフォルトのSQL制約を定義しようとNHibernateに指示しました。 (SQLで直接定義しようとしたのと同じです)。

この場合、カスタム挿入クエリを定義する必要があります。私はそれがhereを文書化されている、のhbm.xmlマッピングでそれを行う方法を知って、それが何かのようになります:文書化されたよう

<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でそれを回避する。すべてのパラメータを受け入れる格納されたprocを使用することで、よりきれいに扱うことができ、どちらの本体が単にidを無視します。

これをFluent NHibernateに翻訳するには、わかりませんが、私はそれを使用しません。

あなたは今でも克服するための大きなハードルを持っています:あなたのIDフィールドにはどのような発電機を使うべきですか?私は適切なものは見当たりません。あなたはNHibernateに嘘をついて、assignedのようなものを言ったかもしれませんが、db側でidが生成されません。あなたがそれを見つけるためにいくつかの自然なIDを持っている場合は、セッションをクリアして、新しく追加された写真を照会する必要があります...

そうでなければ、あなたのケースをサポートするためにcustom id generatorを実装する必要があります。アイデンティティに近いものでなければなりません。しかし、この1つは、as documentedであるため、sql-insertは無視されます。カスタムジェネレータを実装するときに同じ問題が発生する可能性があります。

あなたidは、単純なプロパティではなく、エンティティIDだった場合、あなたは、単にそれがgeneratedあるNHibernateはを言うことができる:

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

しかし、上述のようにIDの、これは限り仕方複雑ですが知っている。

DB側

デフォルトはdbで指定する必要があります。デフォルトを定義しようとしたときに、あなたにエラーが発生した場合は、mysqlの質問を開く必要があり

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

:SQLサーバーを使用すると、デフォルトを定義する正しい方法は次のようなものになるだろう。

しかし、とにかく、あなたはまだNHibernate側でIDジェネレータの問題があります。

関連する問題