2

最初の検査では、Entity Framework 5 のバグのように見えます。

T4 で生成された DbContext および Entity クラスがあります。監視可能なコレクションをサポートするために、デフォルトの T4 テンプレートを少し変更したことに注意してください。

遅延読み込みが有効になっており、これを行っている場合を除いて、アプリケーション全体で正常に機能しています。

courseEnrolment.Student.CourseEnrolments.ToList()

つまり、既にメモリにロードした courseEnrolment に対して、その親 ( Student) にアクセスし、それに関連付けられているすべてのものをロードしCourseEnrolmentsています。これには、元の courseEnrolment も含まれます。これが発生すると、秒CourseEnrolmentは conext (およびLocalコレクション) に正常に遅延ロードされますが、そのナビゲーション プロパティはすべてnull、対応するDynamicProxy.

これは、新しくロードされたCourseEnrolment外観です。通常のプロパティがデータベースから正常にロードされているにもかかわらず、すべてのナビゲーション プロパティが null であることに注意してください。

ここに画像の説明を入力

そして、これは通常のCourseEnrolment外観です。

ここに画像の説明を入力

遅延読み込みに成功したエンティティが、遅延読み込みによって独自のナビゲーション プロパティを満たすことができない理由を知っている人はいますか?


問題の原因に関する詳細情報を更新してください

次の最小限のコードで問題を再現できました。Localこの問題は、私がコレクションを観察していることに関連しているようです。

        var context = new PlannerEntities();

        Debug.Assert(context.CourseEnrolments.Local.Count() == 0);

        context.CourseEnrolments.Local.CollectionChanged += (sender, e) =>
        {
            Debug.Assert(e.NewItems.OfType<CourseEnrolment>().All(x => x.Adviser != null), "newly added entity has null navigatigon properties");
        };

        var c1 = context.CourseEnrolments.Single(x => x.EnrolmentId == "GA13108937");

        Debug.Assert(context.CourseEnrolments.Local.Count() == 1);
        Debug.Assert(context.CourseEnrolments.Local.All(x => x.Adviser != null));

        c1.Student.CourseEnrolments.ToList();

        Debug.Assert(context.CourseEnrolments.Local.Count() == 2);

        Debug.Assert(context.CourseEnrolments.Local.All(x => x.Adviser != null),"some navigation properties were not lazy loaded");

ハンドラー内のアサーションはCollectionChanged失敗します。これは、この時点でナビゲーション プロパティが満たされていないことを示しています。最終的なアサーションは失敗しません。これは、後でObservableCollectionイベントが処理された後、エンティティが満たされていることを示します。

コレクションのCollectionChangedイベントでナビゲーション プロパティにアクセスする方法はありますか?Local

4

2 に答える 2

1

CollectionChanged イベントが呼び出されるまで、遅延ロード プロキシは作成されません。Dispatcher を使用すると、呼び出しがメッセージ キューに置かれ、しばらくしてから実行されます (どれくらい後になるかは決定論的ではありません)。そのため、Debug.Assert が呼び出される前に CollectionChanged イベントが実行され、遅延読み込みプロキシが作成されます。

ただし、Dispatcher は非決定論的であり、競合状態のリスクがあるため、この目的で Dispatcher を使用することは強く避けます。

元のコードのように CollectionChanged イベントを使用するには、遅延読み込みプロキシだけでなく、変更追跡プロキシが必要です。Entity Framework が変更追跡プロキシを生成するには、コレクション、オブジェクト、またはプリミティブ型のすべてのプロパティを virtual として設定する必要があります。

関連する問題: https://github.com/brockallen/BrockAllen.MembershipReboot/issues/290

于 2014-09-05T09:17:17.203 に答える