3

私はよくこのSystem.Data.Entity.DbExtensions Include()メソッドを使用して、リポジトリからのクエリ結果に複雑なエンティティ フィールドを含めます。ただし、エンティティを新しいクラスに投影すると、含まれている複雑なエンティティ フィールドのこの「具体化」が失われるようです。たとえばEvent、リポジトリからオブジェクトを返し、複雑なエンティティ フィールドにアクセスできるようにしたいとしAssessmentます。

public class EventRepository {
...
    public IList<Event> GetEvents() {
        using (var context = new MyDatabaseContext()) {
            return context.Events
                .Include(evnt => evnt.ActualAssessment)
                .ToList();
        }
    }
...
}

Include上記で使用したため、問題なく次のコードを実行できます。

var repoEvents = new EventRepository();
var events = repoEvents.GetEvents();
Console.WriteLine(events[0].ActualAssessment.AssessmentDate.ToString());

しかし、次のように、いくつかの追加情報を使用してEvents をラッパー オブジェクトに投影したいとします。ExtendedEvent

public class EventRepository {
...
    public IList<ExtendedEvent> GetExtendedEvents() {
        using (var context = new MyDatabaseContext()) {
            return context.Events
                .Include(evnt => evnt.ActualAssessment)
                .Select(evnt => new {
                    TheEvent = evnt,
                    SomeExtraData = 123
                })
                .ToList()
                .Select(evntInfo => {
                    return new ExtendedEvent {
                        TheEvent = evntInfo.TheEvent,
                        SomeExtraData = evntInfo.SomeExtraData
                    };
                })
                .ToList();
        }
    }
...
}

私は今、このコードを試して実行します:

var repoEvents = new EventRepository();
var extendedEvents = repoEvents.GetExtendedEvents();
Console.WriteLine(extendedEvents[0].TheEvent.ActualAssessment.AssessmentDate.ToString());

これにより、「ObjectContext インスタンスが破棄されたため、接続が必要な操作には使用できなくなりました」というエラーが表示されます。-新しいラッパーオブジェクトに投影したため、 をActualAssessment使用したにもかかわらず、熱心に読み込まれませんでした。IncludeどうすれActualAssessmentば含まれるようになりますか?

4

1 に答える 1

4

はい、Include予測では無視されます。試すことができるのは、関連するナビゲーションプロパティをプロジェクションの一部にして匿名オブジェクトにすることです。

public IList<ExtendedEvent> GetExtendedEvents() {
    using (var context = new MyDatabaseContext()) {
        return context.Events
            .Select(evnt => new {
                TheEvent = evnt,
                SomeExtraData = 123,
                ActualAssessment = evnt.ActualAssessment
            })
            .ToList()
            .Select(evntInfo => {
                return new ExtendedEvent {
                    TheEvent = evntInfo.TheEvent,
                    SomeExtraData = evntInfo.SomeExtraData
                };
            })
            .ToList();
    }
}

はコンテキストに添付され、自動関係修正は次の場合ActualAssessmentにポポレートしますTheEvent.ActualAssessment

  • 変更の追跡を無効にしない
  • 関係は多対多ではありません

補足として:匿名オブジェクトのリストを作成するという不必要なオーバーヘッドを回避するためAsEnumerable()に、最初の代わりにを使用できます。ToList()

編集

多対多の関係の場合、または変更の追跡が無効になっている場合は、次のように、DBクエリが具体化された後にナビゲーションプロパティを設定する必要があります。

            .Select(evntInfo => {
                evntInfo.TheEvent.ActualAssessment = evntInfo.ActualAssessment;
                return new ExtendedEvent {
                    TheEvent = evntInfo.TheEvent,
                    SomeExtraData = evntInfo.SomeExtraData
                };
            })
于 2012-10-30T16:28:55.993 に答える