2016-11-04 6 views
0

モデルPersonとモデルチームがあります。チームには、Person.PersonIdへのnull可能なTeamleaderIdと仮想のPersonleader {get; set;}を持つFKからPersonへのFKがあります。FK更新時の参照整合性制約違反

いくつかのチームがあり、チームリーダーを持つものもあれば、そうでないものもあります。今では、チームリーダーのプロパティを別のチームリーダーに変更しようとしています。 SaveChangesでは、次の例外が発生します。「参照整合性制約違反が発生しました:リレーションシップの一端の 'Personal.PersonalId'のプロパティ値が 'Team.TeamleaderId'のプロパティ値と一致しませんもう一方の端。

チームリーダーとチームリーダーIDが対応しているため、チームリーダーをヌルにリセットしても機能しません。

リーダーを持たないチームにチームリーダーを初めて設定すると、すべてが機能します。チームリーダーの変更はもはや機能しません。

私は間違っていますか?

public class Person 
{ 
    [Key] 
    public long PersonId { get; set; } 
    // some other... 
    // optional: List of Teams 
} 

public class Team 
{ 
    [Key] 
    public long TeamId { get; set; } 
    // some other... 

    public long? TeamleaderId { get; set; } 

    [ForeignKey("TeamleaderId")] 
    public virtual Person Teamleader { get; set; } 
} 

私はまだいくつかの研究をやっているし、戻ってくる...

うわー:ここ

モデルは以下のとおりです。

敬具、

EDITメイト!そして、非常に奇妙なもののために:

私はウォッチウィンドウ内のエンティティ状態を照会すると、状態は "Modified"であり、レコードは正しく保存されます。エンティティ状態を照会しないと、レコードがSaveChangesに来ると状態は "Unchanged"になり、何も起こりません。この時点でAutoDetectChangesEnabledはtrueです。

これは何ですか?

+0

あなたは 'TeamLeader'プロパティまたは' TeamLeaderId'プロパティを変更していますか?また、サンプルモデルと問題を再現するコード([mcve])を投稿すると良いでしょう –

+0

ChangeTrackingを有効にしていますか?取得時にチームリーダーを読み込みますか?エンティティ状態が正しく設定されているか、データベース内のIDですか? – DevilSuichiro

+0

TeamLeaderIdプロパティを変更します。ナビゲーションプロパティはnullに設定されています。 AutoDetectChangesは、パフォーマンスが悪かったため、falseに変更しました。しかし、これは解決策につながるようです。 AutoDetectChangesをfalseに設定すると、ほとんどの場合動作します。しかし、この特別な場合、私たちは困ってしまう。私はさらなる情報を持って戻ってきます... – Mate

答えて

0

これはそれです。

AutoDetectChangesEnabled = trueはパフォーマンスを低下させるため、データベースオブジェクトを反復処理してコンテキストで追加/更新するときに、AutoDetectChangesEnabled = trueが無効になっています。

オーバーライドされたSaveChangesは、context.ChangeTracker.Entries()、Where(modified ...)を繰り返します。 AutoDetectChangesEnabledの設定に従って、Entries()メソッドはDbContext.ChangeTracker.DetectChanges()を呼び出します。この場合はDetectChangesはで、は呼び出されません。

今、私たちは手動で直接DbContext.ChangeTracker.Entriesを反復する前に、(...修正)DbContext.ChangeTracker.DetectChanges()を呼び出し、そのため

  • ChangeTrackerは正しい値との変更されたレコードが含まれています。

  • 私たち自身の反復/列挙エンティティではパフォーマンスリークがありません。 (例:グローバルにアクティブ化されたAutoDetectChangesEnabledを使用してナビゲーションプロパティが非常に多くないエンティティを12秒間保存すると、SaveChangesでDetectChangesを呼び出すと400msに短縮されました!)。

要約:AutoDetectChangesEnabledをfalseに設定することができます。多くのレコードや多くのナビゲーションプロパティ/複雑なデータツリーがある場合)。また、SaveChangesをオーバーライドする場合は、context.ChangeTracker.DetectChanges()を呼び出してください。すべて正常に動作するはずです。

HTH、種類に関して、 メイト

関連する問題