3

いくつかの親エンティティ ( Order) に対するクエリがあり、そのサブ コレクションまたはプロパティの一部を積極的にロードしたいと考えています。次のようなクエリがあります。

public void QueryMethod()
{
    using (var context = new MyContext())
    {
        var orders = context.Order.Include("OrderProduct")
                                  .Include("OrderProduct.ProductVariant")
                                  .Where(some query)
                                  .ToList();
    }
}

私がやっていることは、この注文コレクションをループし、Order到達したプロパティごとにOrderProductループProductVariantすることです。コンテキストが生きている場合、クエリ メソッド内でこれを行うことができます。しかしProductVariant.OrderProduct、コンテキスト外にアクセスしようとすると、 ObjectDisposedException.

ところで、ProductVariant.OrderProduct変な理由で にアクセスしようとしています。このようにアクセスするべきではないと思いますが、私が言いたいのは、 からOrderProductまではアクセスできますが、 からまでProductVariantはアクセスできません。熱心な読み込みプロパティに追加したにもかかわらず、なぜこのエラーが発生するのか疑問に思っています。両方の方法で機能するはずではありませんか?ProductVariantOrderProductOrderProduct.ProductVariant

どんな助けでも大歓迎です。

4

1 に答える 1

1

コンテキストの外側を取得するという事実ObjectDisposedExceptionは、Entity Framework が参照しているオブジェクトをProductVariant.OrderProductデータベースからの遅延読み込みを介して読み込もうとしていることを示しています。

さて、これは必ずしもProductVariant.OrderProduct正しいエンティティがまだロードされておらず、埋められていないことを意味するわけではありません (このステートメントは奇妙に聞こえます)。おそらくそうです。これは、熱心な読み込みによって読み込まれた逆のプロパティであるためOrderProduct.ProductVariantです。1 対 1 および 1 対多のリレーションシップの場合、EF は、ナビゲーション プロパティが読み込まれるときに、逆方向のナビゲーション プロパティを自動的に設定します ("リレーションシップの修正")。

逆ナビゲーション プロパティが設定されているにもかかわらず、ロード済みとしてマークされるとは限りません。これは、ナビゲーション プロパティごとにコンテキストによって維持されるフラグであり、コードでアクセスするときに遅延読み込みを介してナビゲーション プロパティをデータベースからロードする必要があるかどうかを EF に伝えます。 .

たとえば、1 対多のリレーションシップの場合、リレーションシップの修正によりナビゲーション プロパティが設定されたときに、EF がナビゲーション プロパティを読み込み済みとしてマークしてはならないことは容易にわかります。例: 顧客参照を含む注文をロードする場合 - context.Orders.Include("Customer").Single...-Orders熱心にロードされた顧客のコレクションには、このロードされた注文が含まれます (関係修正のため)。ただし、この 1 つの注文は、この顧客が持っている唯一の注文ではない可能性が最も高いです (または、少なくとも EF は、それが唯一の注文なのか、それともデータベースに他にも注文があるのか​​を知ることができません)。コレクションにアクセスする場合Customer.Orders、通常、この 1 つの注文だけでなく、顧客のすべての注文が返されることを期待します。つまり、顧客の残りの注文をデータベースからロードする遅延読み込みクエリが発生することを期待します。

1 対 1 の関係では、データベース内に複数の関連オブジェクトが存在できないことは明らかであるため、この議論は 1 対 1 の関係についてはあまり説得力がありません。では、この単一の関連オブジェクトが既に読み込まれている場合、EF はなぜ遅延読み込みクエリを実行するのでしょうか?

EF がまだ 1 対 1 の関係の逆ナビゲーション プロパティを読み込もうとする理由はわかりませんが、この点で 1 対多と 1 対 1 の関係を区別していない可能性があります。 . おそらく、EF は、リレーションシップのプリンシパル側がリレーションシップ フィックスアップによって取り込まれている場合、ロード済みとしてマークされず、アクセスすると遅延読み込みが発生するという一般的なルールに従います。OrderProduct(またはがプリンシパルであるかどうかは、コード スニペットから実際にはわかりませんProductVariant。それは単なる推測です。)

とにかく、あなたの状況では、遅延読み込みまたはプロキシ作成 (遅延読み込みの無効化を含む) を無効にします。これは、ブロックInclude内で使用しており、遅延読み込みはここではメリットがないためです。usingあなたが持っている例外は消えるはずです:

using (var context = new MyContext())
{
    context.Configuration.ProxyCreationEnabled = false;

    var orders = context.Order.Include("OrderProduct")
                              .Include("OrderProduct.ProductVariant")
                              .Where(some query)
                              .ToList();
}
于 2013-09-27T18:54:36.263 に答える