我有三个由Entity Framework生成的实体。一个是event
,其中包含名为frogs
和user_bookings
的导航属性。我之前发布了一个相关的问题,关于执行一个似乎有效的子查询,但它阻止我覆盖一个属性的延迟加载。
var evts = from evt in context.events.Include("frogs")
where evt.event_id < 10
select evt;
这样做 - 导航属性frogs
被加载。
但是,当我将LINQ更改为:
var evts = from evt in context.events.Include("frogs")
where evt.event_id < 10
select new
{
Event = evt,
HasBooked = evt.user_bookings.Any(x => x.user_id == 1)
};
尝试访问frogs
时出错,因为ObjectContext不再存在。我尝试从event
类的类定义中删除虚拟,但这只会导致一个空的青蛙列表,当它们肯定在那里时!
答案 0 :(得分:3)
这是by design。如果查询结果是投影,则忽略Include
,即使投影包含可能包含Include
d属性的实体。
我不知道为什么EF会这样实现它。如果投影不包含任何实体,但只是某种类型(匿名或非匿名),则没有Include
目标,因此忽略它是有道理的。但是,如果投影确实包含Include
目标(在您的情况下为Event
),那么在我看来,他们本可以决定做出这样的工作。但是,嗯,他们没有。
也许是因为Include
实际上有效的规则是less obvious than you might expect。在您的情况下,查询的形状会在Include
之后发生变化,因此会被忽略。
您还可以通过查询frogs
:
from evt in context.events.Include("frogs")
where evt.event_id < 10
select new
{
Event = evt,
Frogs = evt.frogs,
HasBooked = evt.user_bookings.Any(x => x.user_id == 1)
};
现在每个Event
也会填充frogs
个集合(因为关系修正)。但有两个陷阱。这些集合未被标记为已加载,因此 -
这意味着要完成这项工作,您必须禁用延迟加载。