2

ナビゲーション プロパティを介してコレクション オブジェクトからオブジェクトを削除すると、深刻なパフォーマンスの問題が発生します。EntityCollection.Remove が呼び出されると、完了するまでに 8 分 (!!!!) かかります

詳細: CollectionObject X には 65.000 個のオブジェクトがあります。コレクションから削除する必要があるのは、そのうちの 1 つだけです。

関連する独自のコードはあまりありません。つまり、EntityCollection は (生成されたコード) を介して作成されます。

RelationshipManager.GetRelatedCollection<...>(<relationShipName>, <targetRoleName>)

そして実際の Remove は単純に

EntityCollection<Type>.Remove

実際の削除を行う前に、EntityFramework が 65.000 個のオブジェクトすべてをロードしていると思われます。ただし、これまでのところ、この仮定を証明することはできませんでした。

何か案は?

ありがとうフランク

追加情報: この便利なリンクを見つけました: EF は EntityCollection を構築しますが、IQueryable が必要です 。この問題の本当の原因は、Remove を実行するときの EntityCollection の動作です。

私は一種の回避策を見つけて、リレーションの小さい側を使用しました。つまり、オブジェクト A からオブジェクト B へのリレーションを削除したい場合、オブジェクト A に 65000 個のオブジェクトがある場合、パフォーマンスが低下するオブジェクト B 側からリレーションを削除します。オブジェクト B は、たとえば 10 個のオブジェクトのみに関連付けられているため、問題ありません。明らかに、これは問題に対する満足のいく一般的な解決策ではありません。

4

1 に答える 1

1

はい、削除する前にすべてのオブジェクトをロードしている可能性があります。これを確認するには、SQL Server に付属の SQL プロファイラー ツールを使用できます。

オブジェクトの削除に関する限り、このナビゲーション プロパティにアクセスする必要がある場合は、EntityReference で CreateSourceQuery を使用できます。ナビゲーション プロパティが Candles と呼ばれる場合、EntityReference はデフォルトで CandlesReference と呼ばれます。したがって、削除は次のようになります。

var victim = entity.CandlesReference.CreateSourceQuery().Single(c => .....);
context.DeleteObject(victim);
context.SaveChanges();

これにより、実行されたはずのクエリが取得され、最初にすべてを取得することなく、必要なものを選択する機会が与えられます。

必要な情報があると仮定すると、次のように直接クエリを実行する方が効率的かもしれません

var victim = context.Candles.Single(c => ....);
于 2012-04-24T18:28:10.960 に答える