2017-02-28 11 views
0

重複値を持つ行を更新するときに一意に制約される重複値を削除するようにnHibernateに指示する方法はありますか?例えばNHibernateの一意制約重複の場合の除外

Id | OtherId | Animal 
------------ 
1 | 1  | Dog 
2 | 1  | Cat 
3 | 1  | Bear 
4 | 2  | Dog 

更新番号3イヌに(OtherId及び動物が複合的制約一意である)、この

Id | OtherId | Animal 
1 | 1  | NULL 
2 | 1  | Cat 
3 | 1  | Dog 
4 | 2  | Dog 

EDITをもたらすはずである:

私ができましたテーブルにユニークなインデックスを作成して問題を解決する

CREATE UNIQUE INDEX [Id_OtherId_Animal_Index] 
ON [dbo].[Animals] (OtherId, Animal) 
WHERE Animal IS NOT NULL; 

このようにして、重複(1、犬)の挿入を防ぎ、引き続き(2、犬)を許可します。これにより、複数(1、NULL)を挿入することもできます。

次に、フレデリックの提案に基づいて、重複している場合はBEFORE挿入を確認するために私のサービス層を編集しました。そうであれば、その動物列は一意に制約されます。

答えて

1

この答えは、私はNHibernateは、または任意の他のORMには、このような機能はありませんかなり確信しているOPの質問にかなりのchangesによって

を時代遅れにされています。

ところで、Dogに更新した後、Id3をCatに更新するにはどうすればよいですか?

Id | Animal 
1 | 
2 | 
3 | Cat 

ことは、ID 1 & 2は今、あまりにもユニーク制約違反になり、空の文字列値を、持っていることを意味します。
値がnullの場合、ANSI準拠であるかどうかによって異なります(NULLはnullとはみなされません)。これは、少なくともユニークなインデックスの場合、私が知っているバージョンのSQL Serverの場合とは異なります。 (私はユニークな制約の場合をテストしていません)

とにかく、この種のロジックは、他のいくつかの行で追加の更新をもたらす行を更新するため、明示的に処理する必要があります。

あなたは多くのことのためのオプションがあります:Animalプロパティにそれぞれ代入する前に

  1. を、別の1は、その名前を持っている場合は見つけるためのDBを照会し、その別の1に適切な行動を取ります。この最初のものを実際に更新する前に処理されるように、この他のものを処理した直後にフラッシングに注意してください。
  2. または、NHibernateに任意のエンティティの更新をキャッチするためにevent or an interceptorを挿入し、重複のチェックを追加します。スタックオーバーフローには、このようなNHibernateイベントまたはインターセプタの例があります(one)。
    しかし、すでにセッションをフラッシュしている間に他のいくつかの変更をフラッシュすると、おそらく問題が発生するため、あなたのケースは少し難しいでしょう。例として、IInterceptor.OnPrepareStatementというSQL文を直接修正しなければならないかもしれません。
  3. DBのトリガーでそれを処理してください。
  4. または、一意の制約のために失敗したフラッシュを検出し、それを分析し、適切な処置を講じます。

3番目のオプションは、他のオプションよりも簡単で堅牢です。

+0

ありがとうございました。実際に何かが空の文字列またはnullに両方の列を更新すると、それがユニークな制約違反をトリガしないと考えたのですが、#1アプローチとハンドルこれはサービス層では、ビジネスロジックのように聞こえるようになりました。 – kotsumu

関連する問題