2012-04-03 23 views
28

ちょっと私は、inprocキャッシングとエンティティフレームワークの束を持つアプリケーションを持っています。エンティティに更新を書きたいときは、キャッシュされたコピーを再アタッチします。私は文脈のライフサイクルの中で私が付けてきたすべてのものを追跡するので、私はそれらを二度付けようとしません。Entity Framework:多対多関係の参照整合性制約違反

は、私は、次の言う(これは正常に動作し、本当に速いです、ほとんどの場合、非常にまれ)を取り付けないで発生したエラーしている:

参照整合性制約違反が発生しました:定義するプロパティ 値を参照制約は、関係のプリンシパルオブジェクトと依存オブジェクトの間で一貫性がありません。

正常に見えるエンティティをよく見ています。私は、この問題は、フィックスアップが実行されているときに外部キーの接続/切断が原因であると考えています。

このエラーに関する情報を得るには良い方法がありますか、エンティティがEFが期待していない状態にあった以外の理由で発生する可能性がありますか?

EDIT: DBダイアグラム

enter image description here

(私も単純化のためのモデルオフの正規のプロパティの束をみじん切りしました、私はちょうど図を作るためにEDMXツールを使用codefirst使用しています注意してください)
+0

最初にコードを使用しているか、モデルを最初に使用していますか?モデルの詳細、エラーに関連する表/クラス、多対多マッピングの方法あなたが最初にコードを使用している場合、私はすべての側面を制御して同様のことを避けるために、関係を「手動で」行うことを好む。反対に、参照整合性エラーはそれを意味する可能性が高い - 私はそれがオブジェクトの状態だとは思わない、それは私が推測する同様の方法で現れることができる。 – NSGaga

+0

私のモデルはCodeFirstを使用しています。私のモデルは本当にシンプルです。暗黙のうちにダイアグラムを投稿します。 –

+0

ルーク、CFパートを教えてください。どのようにマップしますか?モデルクラスはどのように見えますか?これを手助けできるようにする。 – NSGaga

答えて

40

多対多の関係に加えて、モデルに明らかにあるPersonLocationの一対多の関係でエラーが発生する可能性があります。たとえば、次のコードが例外をスローします:

using (var context = new MyContext()) 
{ 
    var person = new Person 
    { 
     CurrentLocationId = 1, 
     CurrentLocation = new Location { Id = 2 } 
    }; 
    context.People.Attach(person); // Exception 
} 

「を参照制約を定義するプロパティの値は、」外部キープロパティ値CurrentLocationIdと主キーの値CurrentLocation.Idです。これらの値が異なる場合、例外がスローされます。

この例外は、このタイプの関連付けに対してのみ、モデル内の参照制約を定義するプロパティしかないため、外部キーの関連付けに対してのみスローすることができます。それは独立した団体のために放棄することはできません。すべての多対多の関係は独立した関係(モデル内の外部キープロパティなし)であるため、多対多の関係ではなく、一対一の関係に関係していると思います。

+1

それで 'Location'sを' Person's( 'Location's IDが与えられている)に設定するにはどうしたらいいですか?私のシナリオでは、それは数多くの問題である。この例外に対する一般的な解決策は何ですか、どうすれば回避できますか? – Shimmy

+1

@Shimmy:ナビゲーションプロパティを 'null'(この場合は私が行う)として残すか、ナビゲーションプロパティに設定されたエンティティのFKプロパティ値とPK値が同じであることを確認するだけです。しかし、私の理解では、この例外は多対多の関係では発生しません。これはFK関連のみの例外であり、多対多関係はFK関連ではなく独立した関連です。 – Slauma

+0

私のシナリオで私は 'カテゴリ'と 'ビジネス'があります。各事業は複数の「カテゴリー」を持つことができます。私は添付するカテゴリーIDのリストを持っていますが、どのようにすればいいですか? – Shimmy

2

私はちょうど同じ問題を抱えていました。私の解決策は、私が関連付けにマッピングを追加し、参照制約を設定したことでした。

問題を解決するために、アソシエーションのマッピングウィンドウを開き、マッピングを削除するリンクがありました。マッピングの詳細ウィンドウが完了すると、マッピングは許可されません。参照制約を追加すると、マッピングが残ります。

他の誰かがこのエラーメッセージの解決策を将来的に探している場合は、投稿する価値があるかもしれません。

1

@LukeMcGregorやあ、

私は同じ問題を持っている人のような異なる視点を提供することができると思います。

私は必要なチェックをすべて実行した後、私はこのエラーを得ることを好むと言います。

私のシナリオでは、ミスマッチエラーの原因となったオブジェクトを含めることにしました。これは、シナリオ内のロケーションオブジェクトです。 IDを持つオブジェクトを追加すると、前のオブジェクトのID(更新されていないID)が更新されたIDと一致しないため、このエラーが発生します。

しかし、大きな問題ではありません。解決策として。まだUI側にある場合、オブジェクトがまだ存在する場合、オブジェクトはまだ含まれている可能性があります。

ユーザーからの更新要求を受け取ったときにオブジェクトを空にします。 (= Null)または、サービス側の更新(添付、変更など)の前にユーザーが更新したIDでオブジェクトを更新し、このように更新します。

これだけです。それはデータベースと図にそのまま残ることができます。

1

私は非常によく似た例外に出くわした:

"A referential integrity constraint violation occurred: 
The property value(s) of 'ObjectA.PropertyX' on one end of a relationship 
do not match the property value(s) of 'ObjectB.PropertyY' on the other end." 

理由は、このでした:ウェブAPIのクライアント側はObjectAに、この例では、ナビゲーションプロパティ((を含むオブジェクト全体でPUTリクエストを送信し より正確にはObjectB.ObjectA)はナビゲーションプロパティであり、クライアントによって完全に提供されました)。これは、クライアントがサーバーからオブジェクト全体を受け取り、小さな変更を加えたままサーバーに戻すために発生します。

一方、ObjectB.PropertyYが変更されたばかりです(これがPUTリクエストの最初の理由です)。

ObjectB.PropertyYは同じオブジェクトObjectA(外部キー)への参照であったため、EFはこれを調整しようとしましたが、上記の例外で失敗しました。

解決策は単純であった:SaveChangesメソッド前

ObjectB.ObjectA = null; 

()完全にこれを解決しました。

私はこれが誰かを助けてくれることを願っています。