如何在计划的实体框架对象中包括复杂的实体字段? [英] How to include complex entity fields in a projected entity framework object?

查看:59
本文介绍了如何在计划的实体框架对象中包括复杂的实体字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常使用System.Data.Entity.DbExtensions Include()方法使复杂的实体字段包含在我的存储库的查询结果中.但是,当我将实体投影到新类中时,似乎丢失了包含复杂实体字段的这种具体化".例如,假设我想从我的仓库中返回一个Event对象,并且能够访问复杂实体字段Assessment:

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

由于上面使用的Include,我随后可以顺利运行以下代码:

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

但是说我现在想将Event s投影到带有一些额外信息的包装对象ExtendedEvent中,例如:

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

这给了我错误"ObjectContext实例已被处置,并且不能再用于需要连接的操作". -因此,尽管我使用了Include,但尚未立即加载ActualAssessment,这显然是因为我将其投影到了新的包装器对象中.如何使ActualAssessment被包含?

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?

推荐答案

是的,Include在投影中被忽略.您可以尝试的是使相关导航属性成为投影到匿名对象中的一部分:

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

ActualAssessment将附加到上下文,并且自动关系修复将填充TheEvent.ActualAssessment 如果

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

  • 您不会禁用更改跟踪
  • 这种关系不是多对多的

请注意:您可以使用AsEnumerable()而不是第一个ToList()来避免创建匿名对象列表的不必要的开销.

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.

修改

对于多对多关系或在禁用更改跟踪的情况下,必须在实现数据库查询后设置导航属性,例如:

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

这篇关于如何在计划的实体框架对象中包括复杂的实体字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆