How to include complex entity fields in a projected entity framework object?

c#, entity-framework, linq, repository, repository-pattern

Solution

Yes, `Include` is ignored in projections. What you can try is to make the related navigation property part of your projection into the anonymous object:

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();
    }
}

The `ActualAssessment` will be attached to the context and automatic relationship fixup will popolate `TheEvent.ActualAssessment` if

- you don't disable change tracking

- the relationship is not many-to-many

As a side note: You can use `AsEnumerable()` instead of the first `ToList()` to avoid the unnecessary overhead of creating a list of anonymous objects.

Edit

For a many-to-many relationship or in case of disabled change tracking you must set the navigation property after the DB query is materialized, like so for example:

            .Select(evntInfo => {
                evntInfo.TheEvent.ActualAssessment = evntInfo.ActualAssessment;
                return new ExtendedEvent {
                    TheEvent = evntInfo.TheEvent,
                    SomeExtraData = evntInfo.SomeExtraData
                };
            })

Problem

I often use the `System.Data.Entity.DbExtensions` `Include()` method to cause complex entity fields to be included in query results from my repositories. However, when I project my entities into new classes, I seem to lose this "concretization" of included complex entity fields. For example, say I wanted to return an `Event` object from my repo, and be able to access the complex entity field `Assessment`: ``` public class EventRepository { ... public IList<Event> GetEvents() { using (var context = new MyDatabaseContext()) { return context.Events .Include(evnt => evnt.ActualAssessment) .ToList(); } } ... } ``` I can then run the following code without a hitch because of the `Include` I used above: ``` var repoEvents = new EventRepository(); var events = repoEvents.GetEvents(); Console.WriteLine(events[0].ActualAssessment.AssessmentDate.ToString()); ``` But say I now want to project the `Event`s into a wrapper object `ExtendedEvent` with some extra info, like this: ``` 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(); } } ... } ``` I now try and run this code: ``` var repoEvents = new EventRepository(); var extendedEvents = repoEvents.GetExtendedEvents(); Console.WriteLine(extendedEvents[0].TheEvent.ActualAssessment.AssessmentDate.ToString()); ``` This gives me the error "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection." - so `ActualAssessment` has not been eager-loaded despite my use of `Include`, apparently because I projected it into a new wrapper object. How can I cause `ActualAssessment` to be included?

Original source