0

DevForce 2010 バージョン 6.1.15.0 から IdeaBlade を使用して Silverlight 4 でビルドされたアプリケーションを継承しました。バックエンド データベースは SQL Server 2008 です。機能していない更新や挿入を追跡しているときに、IdeaBlade.EntityModel.EntityManager.SaveChangesAsync() の呼び出しから次のエラーが発生していることがわかりました。

「参照された一時 ID を含む 1 つまたは複数のエンティティが提供されたエンティティのリストにありません。欠落しているエンティティには次が含まれます: リビジョン: -100。詳細については、例外メンバーを参照してください」

さらに掘り下げると、次の追加情報が明らかになりました。

「UPDATE ステートメントは FOREIGN KEY 制約 "FK_valuation_revision" と競合しました。データベース "XX"、テーブル "Revision"、列 'RevisionID' で競合が発生しました。ステートメントは終了しました。」

さらに深く掘り下げると、次のことがわかりました。

  1. 関連する 2 つの主なクラスは次のとおりです。評価と改訂
  2. Valuation には、リビジョンのコレクションがあります。データベースでは、これは、Valuation テーブルの PK を参照する Revision テーブル (null 以外) の FK によって表されます。
  3. さらに、Valuation には CurrentRevision への参照があります。これはデータベース上で、リビジョン テーブルの PK を参照する評価テーブルの FK (リビジョンがない場合は null になる可能性があります) として表されます。
  4. 問題のコードでは、次のように新しい Revision オブジェクトが作成されます。

    myNewRevision = new Revision { Valuation = myExistingValuation };

    この時点で、myNewRevision は、EntityState が「追加済み」の IdeaBlade.EntityModel.Entity です。

  5. オブジェクトにさらにいくつかの変更を加えた後、次のコードが実行されます。

    EntityManager.AddEntity(myNewRevision);

    MyNewRevision の状態が呼び出し前と呼び出し後と同じであるため、上記の AddEntity への呼び出しは何も達成していないようです。

  6. 次に、新しく作成されたリビジョン オブジェクトを保存しようとします。

    SaveChangesAsync(new[] { myNewRevision }, null, RevisionCallback, null);

    上記のステートメントは try...catch ブロック内にあり、エラーはスローされませんが、RevisionCallback ルーチンは実行されません。また、myNewRevision の EntityState はまだ「追加済み」であり、キーはまだ -100 として表示されています。

  7. 次に、既存の評価オブジェクトが新しいリビジョンへの参照で更新されます。

    myExistingValuation.CurrentRevision = myNewRevision;

    これにより、myExistingValuation の EntityState が "Unchanged" から "Modified" に変更されます。

  8. 最後に、コードは変更を Valuation オブジェクトに保存しようとします。

    SaveChangesAsync(new[] { myExistingValuation }, null, ValuationCallback, null);

  9. この呼び出しの結果、ValuationCallback が呼び出されますが、myExistingValuation は引き続き "Modified" として表示され、myExistingValuation.CurrentRevision への参照は -100 のキーと "Added" の EntityState を持つ myNewRevision を参照します。コールバック メソッドに返された EntitySaveOperation オブジェクトには Exception == null、HasError = true があり、エラーはこの質問の冒頭で説明したものです。あれは、

    「参照された一時 ID を含む 1 つまたは複数のエンティティが提供されたエンティティのリストにありません。欠落しているエンティティには次が含まれます: リビジョン: -100。詳細については、例外メンバーを参照してください」

    「UPDATE ステートメントは FOREIGN KEY 制約 "FK_valuation_revision" と競合しました。データベース "XX"、テーブル "Revision"、列 'RevisionID' で競合が発生しました。ステートメントは終了しました。」

    データベースは更新されません。

助言がありますか?SaveChangesAsync への最初の呼び出しからのコールバック ルーチンが実行されないのはなぜですか? どうすれば更新を機能させることができますか?

4

1 に答える 1

0

RevisionCallback が呼び出されないのは奇妙ですが、次の手順を実行するときに async メソッドが完了していない可能性があります。

DevForce 2010 は新しいタスクベースの非同期パターンを使用しないため、ここでは非同期メソッドで try/catch を使用できません。そのため、コールバックまたは完了ハンドラーに例外が返されるか、EntityManager に設定されている場合は EntityServerError ハンドラーに返される可能性があります。

保存リストを指定しない限り、DevForce は既定でエンティティへのすべての変更をキャッシュに保存しますが、そのリストには 1 つの項目のみが含まれている必要はありません。一時 ID を持つエンティティの保存を行う場合、一時 PK または FK を持つすべてのエンティティは、SaveChangesAsync に渡される保存リストに含まれている必要があります。保存が正常に完了すると、DevForce は FK への修正を自動的に処理します。

代わりに次のようなことができない理由はありますか:

myNewRevision = new Revision { Valuation = myExistingValuation };
myExistingValuation.CurrentRevision = myNewRevision; 
SaveChangesAsync(ValuationCallback);
于 2014-06-09T22:12:14.603 に答える