0

我正在使用带有实体框架的代码优先方法和存储库模式来从我的数据库中获取实体。在我的数据模型中,每个OverallEvent都有很多EventInConcept孩子。我希望我的GetEvents方法返回一个IListof OverallEvents,并且我希望将上述关系的子项具体化,以便可以在我的DbContext(即AssessmentSystemContext)之外访问它们。这是我目前拥有的代码:

public IList<OverallEvent> GetEvents() {
    using (var context = new AssessmentSystemContext()) {
        return context.OverallEvents
            .Select(evnt => new {
                OverallEvent = evnt,
                // evnt.EventsInConcept is a public virtual ICollection<EventInConcept>
                ConcreteEventsInConcept = evnt.EventsInConcept
            })
            .AsEnumerable()
            .Select(evntData => {
                evntData.OverallEvent.EventsInConcept = evntData.ConcreteEventsInConcept.ToList();
//              foreach (var eic in evntData.OverallEvent.EventsInConcept) {
//                  eic.Name = eic.Name;
//              }
                return evntData.OverallEvent;
            })
            .ToList();
    }
}

它给了我一个OverallEvent实体列表,这很好,但问题是如果我尝试访问子关系EventsInConcept,我会得到一个错误。例如:

EventRepository repoEvent = new EventRepository();
var gotEvents = repoEvent.GetEvents();
var firstEventInConcept = gotEvents[0].EventsInConcept.FirstOrDefault();

...给我错误“ObjectContext 实例已被释放,不能再用于需要连接的操作。”

我从对较早问题的回答中了解到,如果我投影EventsInConcept到一个包装器对象中,然后在以后的.Select调用中显式设置它(即。evntData.OverallEvent.EventsInConcept = evntData.ConcreteEventsInConcept.ToList();),它将具体化这个 one:many 关系,我将能够EventsInConceptDbContext,但它在这里不起作用。请注意,如果我取消注释foreach循环,它就会开始工作,所以要让它工作,我必须EventsInConcept. 我真的不想这样做(我正在选择一个任意属性,.Name,无论如何感觉不对)。有没有更好的办法?

4

1 回答 1

1

禁用此查询的延迟加载。在这种情况下以及在检索到实体后处置上下文时,它是没有用的:

public IList<OverallEvent> GetEvents() {
    using (var context = new AssessmentSystemContext()) {
        context.Configuration.LazyLoadingEnabled = false;
        return ...
    }
}

当您使用投影(而不是急切或显式加载)时,EF 可能无法识别集合已加载,并在您访问集合时立即触发延迟加载。

于 2012-12-14T16:17:06.240 回答