12

私は MVC で Entity Framework 4 を使用しており、コントローラー メソッドが戻る前にビューで使用したい参照エンティティが読み込まれていることを確認する必要があります。

ObjectContext インスタンスは破棄されており、接続を必要とする操作には使用できなくなりました。

コンテキストから直接選択する場合は、Include(string)メソッドを使用して、生成された SQL クエリにそれらを強制的に含めることができます。

var sellers = context.Sellers.Include("Recommendations.User").ToList();

ただし、(たとえば) エンティティを受け入れ、すべてのアイテムを読み込む必要があるヘルパー メソッドがある場合、Include使用できるメソッドはありません。

void Test(Seller seller)
{
    // ensure all recommendations and their users are loaded
}

ブルート フォース アプローチは、それらをループすることです。

foreach (var recommendation in seller.Recommendations)
    recommendation.User.ToString(); // just force a load

推奨事項が 100 件ある場合、バックグラウンドで 101 件の SQL クエリが作成されます。理想的には、SQL への 1 回の旅行ですべてのRecommendationANDオブジェクトをロードするメソッド/アプローチが必要です。User

私にお金をみせて。

編集これが良いアーキテクチャか悪いアーキテクチャかについて議論することにあまり興味がありません。質問のためにシナリオを単純化しました。私が求めていることを EF API で実行できますか?

編集2

Ladislav の編集は、新しいアプローチへの希望をもたらしましたが、私はまだそこまで進んでいないようです。

私はこれを介して私が望むものを達成することができます:

context.Sellers.Include("Recommendations.User").Single(s => s.Id == seller.Id);

このアプローチは使用できませんLoadProperty...

context.LoadProperty(seller, "Recommendations.User");

...エラーで失敗するため...

指定されたナビゲーション プロパティ Recommendations.User が見つかりませんでした。

コンテキストへの参照がない場合、これらのアプローチはどちらも機能しません。

4

4 に答える 4

5

これは古い質問ですが、EF6 では、エンティティに依存するオブジェクトを次のように読み込むことができます

context.Entry(seller).Collection(s => s.Recommendations).Query().Include(r => r.User)).Load();

それは、指定されたすべてRecommendationsとそれらに関連するものをロードしますUsersseller

于 2014-02-26T18:44:54.883 に答える
3

これは、あなたの場合、GetFullSeller (インクルードによって読み込まれるすべてのプロパティ) や GetSeller (基本エンティティのみ) などのメソッドを公開する必要があるリポジトリの仕事だと思います。

編集:

EF v4 でナビゲーション プロパティを読み込む方法はいくつかあります。

  • Eager ローディング (Include を使用)
  • 遅延読み込み
  • ObjectContext.LoadPropertyによる明示的な読み込み(POCO では機能しません)

自動ロードはありません。

于 2010-09-08T19:49:15.040 に答える
2

私も同じ状況です。EF では 101 クエリの問題に陥りやすいと思います。

解決策として、(EF によって生成された) Seller クラスの部分クラスを作成し、IQueryable を返す GetSubclassNameQ と、熱心な読み込みで IQueryable を返す GetSubclassNameQFull を実装することができます。

public partial class Seller{

  public IQueryable<Recommendation> GetRecommendationsQ(EntityContainer entitycontainer) {
    return entitycontainer.Recommendations;
  }      

  public IQueryable<Recommendation> GetRecommendationsQFull(EntityContainer entitycontainer) {
    return this.GetRecommendationsQ(entitycontainer).Include("Recommendations.User");
  }

  public IQueryable<Recommendation> GetRecommendationsQ() {
    return GetRecommendationsQ(new EntityContainer());
  }

  public IQueryable<Recommendation> GetRecommendationsQFull() {
    return this.GetRecommendationsQ().Include("Recommendations.User");
  }

}
于 2010-11-03T17:03:28.830 に答える
0

実際のドメイン オブジェクト ( ) をビューに渡すのではなくEntityObject、コントローラーを使用して、ビューが実際に表示する必要があるものをより適切に表す Model オブジェクトにマップすることができます。これにより、ビューに必要なロジックの量が減り、コンテキストの有効期限が切れた後に EntityObject を渡すのを回避できるという嬉しい副作用があります。

編集に基づいて編集します。

いいえ、API には、単一のエンティティ オブジェクトを取得し、同時に読み込まれたそのタイプの他のすべてのエンティティ オブジェクトを、特定のプロパティで一気に遅延入力する方法がありません。Include質問に示されているような言及を使用して、最初にすべてのアイテムを引き出す方がよいでしょう。

于 2010-09-08T19:59:14.017 に答える