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

好久不见. 提交于 2019-12-24 01:53:12

问题


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 Events 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?


回答1:


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


来源:https://stackoverflow.com/questions/13143268/how-to-include-complex-entity-fields-in-a-projected-entity-framework-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!