1

新しい子関係を既存の親オブジェクトに追加しようとすると、エンティティは親オブジェクトをmodifiedとして更新するのではなく、newとして挿入しようとします。重複したキーを挿入しようとしているというエラーが表示されます。

これは本当に私を困惑させています。モデルを新しいリレーションで更新するまで(コードではなくデータベースからの更新を介して)、このように動作しませんでした。同じ多対多パターンを持つ同じコンテキスト内の他のテーブルでは、このエラーは発生しません!

子オブジェクトをコンテキストに追加し、ナビゲーション プロパティではなく ID 値を慎重に設定すると、正常に保存されることがわかりました。ただし、修正プロセスでは子オブジェクトがナビゲーション コレクションに追加されないため、他の場所でロジックの問題が発生します。

私のモデルには、次のような多対多の関係があります。

option -< optionUnit >- 単位

Option オブジェクトと Unit オブジェクトの両方が存在し、コンテキストに読み込まれます。

通常、ブリッジ テーブルを作成し、ナビゲーション プロパティを次のように設定します。

bridge = new OptionUnit()
{
    OptionUnitId = Guid.NewGuid(),
    Unit = SelectedUnit,
    Option = SelectedOption,
};
//Context.OptionUnits.Add(bridge); //added to context via the navigation properties

しかし、今回は、エンティティは SelectedOption を新規として挿入しようとしました (そのエンティティの状態は保存時に変更され、新規または切り離されていません)。

これを回避するには、ブリッジを作成して ID のみを設定する必要がありました。保存時にエラーは発生しませんが、予想どおり、修正によって SelectedOption.OptionUnits に自動的に追加されません。手動でコレクションに追加すると、保存エラーが再び発生します。

bridge = new OptionUnit()
{
    OptionUnitId = Guid.NewGuid(),
    //Unit = SelectedUnit,
    UnitId = SelectedUnit.UnitId,
    //Option = SelectedOption,
    OptionId = SelectedOption.OptionId,
};
Context.OptionUnits.Add(bridge);

これは、オプション エンティティの関係でのみ発生しているようです。optionUnit >- Unit の間の他の関係には問題がなく、期待どおりに機能します。

関係に問題があるようですが、どこを見ればよいかわかりません。この動作の原因、修正方法、および今後発生しないようにする方法を知る必要があります....

4

2 に答える 2

3

信じられないことに、Julie Lerman がまさにこの問題とその理由についての素晴らしい MSDN 記事を発表しました。記事はこちらからご覧いただけます

ジュリー自身の言葉で:

これが発生する理由は、DbSet.Add メソッドを使用すると、ルート エンティティの状態が「追加済み」とマークされるだけでなく、コンテキストが以前に認識していなかったグラフ内のすべてのものが追加済みとマークされるためです。開発者がオブジェクトに既存の Id 値があることを認識している場合でも、Entity Framework はその EntityState (Added) を尊重し、既存の Id に関係なく、オブジェクトのデータベース挿入コマンドを作成します。

要するに、ここで何が起こっているかというと、あなたが と言うとContext.OptionUnits.Add(bridge);、Option オブジェクトと Unit オブジェクトもそれに追加しようとしていると考えているということです。代わりに、(彼女が言及しているように) FK を使用してから追加する必要があります。

2回目の試みであなたがやろうとしていることだと思いますが、SelectedOption.OptionUnits. 保存直後に確認しようとしていますか?その場合、その値は Entity Framework によってプルされるときにメモリにキャッシュされるため、表示されません。その後、そのオブジェクトを再度表示する必要があります。

于 2013-04-10T15:16:40.883 に答える
0

問題が見つかりました。子項目を追加した後、いくつかのロジックを実行して合計を更新します。問題は、RaisePropertyChanged("sum") の代わりに RaiseDataMemberChanged("sum") を使用したことです。RaiseDataMemberChanged() は、エンティティ内の何かを変更済みとしてマークする必要があり、これがこの問題を引き起こしていました。IronMan84 に感謝します。

于 2013-04-11T14:18:42.773 に答える