1

STEに関する数え切れないほどの問題の中で、私は今これに直面しています。これは些細なことですが、そうではありません。

簡単にするために、標準の請求書、注文、製品のシナリオを想定します。

請求書を受け取り、請求書を元の層に送り返す前に一部の製品の注文を追加する、ステートレスではない(何らかの理由で)層があるとします。

これは単純に聞こえますが、実際には、単純な解決策が見つからないSTEの問題です。問題は、注文に割り当てる製品エンティティのコレクションをどのように保持するかです。私が見ているように、私はこれらの方法の1つでそれをしなければならないでしょう、それはすべて大きな欠点を持っています:

請求書エンティティに発注する注文ごとに、データベースで製品エンティティをクエリします。

欠点:同じ製品が複数の注文で使用されている場合、請求書の変更がデータベースに保存されると、EFは例外をスローします。これは、同じ製品キーの複数のインスタンスがコンテキストで許可されていないためです。複数の注文で発生する製品は、一度だけ照会されてから注文間で共有されるようにすることはできましたが、それは間違いなく事態を複雑にします。

もう1つの欠点は、製品エンティティ(または別のドメインシナリオの同等のエンティティ)がかなり大きい場合、またはアプリケーション層で製品をデータベースにクエリすることが何らかの理由で実用的でない場合のパフォーマンスです。

アプリケーションの有効期間の開始時に、すべての製品エンティティについてデータベースにクエリを実行します

これは、製品のリストがめったに変更されない場合にユーザーアプリケーションに製品のリストを保持する場合の典型的なシナリオです。私の場合、データベースにクエリを実行したくありません。「製品」タイプのリストはアプリケーションの存続期間中に変更されないため、パフォーマンスは重要な問題であり、システムはデータベースが一時的に利用できなくなることに対して堅牢である必要があります。 「製品」と同等のエンティティのキ​​ャッシュされたコレクションを保持します。

欠点:ここでの主な欠点は、キャッシュされた製品を新しい注文エンティティに割り当てると、メモリリークが発生することです。その理由は、STEによって生成された「Fixup」メソッドが、製品のカスケード削除を処理するために、イベントハンドラーを製品のChangeTrackerにフックアップするためです。そのイベントハンドラーは、新しい注文とキャッシュされた製品を接続したままにして、キャッシュの存続期間中に追加されたすべての注文を蓄積します。解決策は、STEのある種の「フリーズ」プロパティを実装することです。これにより、変更の追跡が無効になるだけでなく、ナビゲーションプロパティの割り当て後も、エンティティと変更トラッカーの状態が変更されません。STEコードには多くの副作用があり、変更が困難なため、このような「フリーズ」変更を作成するのは難しい場合があります。

製品エンティティのクローンを作成する

ここでは、アプリケーションの有効期間の開始時に製品が照会されますが、製品エンティティを使用する代わりに、製品を注文に割り当てるときにクローンが作成されます。これにより、メモリリークの問題は解決されますが、クローン作成を実装して維持する必要があります。クローン作成をサポートするためにSTE.ttスクリプトを書き直すのはそれほど難しくない可能性があります。ただし、エンティティコンテキスト内の複数のエンティティが同じキーを共有する場合は問題が発生します。

4

0 に答える 0