使用Include()进行预先加载

时间:2009-03-21 11:35:12

标签: entity-framework linq-to-entities

想象一下这个案例:

var locations = from Locations in this.LocationDataContext.Locations
                                      .Include("ChildLocations")                      
                where
                     (Locations.LocationType.ID == 3) 
                select
                     Locations;

此查询将加载类型为== 3的所有位置以及所有相关的子位置,确定。但我想弄清楚的是如何过滤正在加载的子位置。如果位置有3个孩子的位置怎么办?

也许是这样的? (因为ChildLocations是一组实体而无效)

var locations = from Locations in this.LocationDataContext.Locations
                                      .Include("ChildLocations")                      
                where
                     (Locations.LocationType.ID == 3) &&
                     (Locations.ChildLocations.LocationType.ID == 2)
                select
                     Locations;

谢谢。

1 个答案:

答案 0 :(得分:4)

实体框架永远不会实现部分完成的实例。换句话说,您不能仅使用其某些的ChildLocations来实现位置。这将是一个“不完整”的对象,实体框架不允许这样做。

但是,有一些解决方法。如果您只需要来自ChildLocations的信息而不是位置本身,请选择:

from Locations in this.LocationDataContext.Locations
where Locations.LocationType.ID == 3
from ChildLocation in Locations 
where ChildLocation.LocationType.ID == 2
select ChildLocation;

在这种情况下,由于我们只选择ChildLocations,因此可以只选择其中一些,因为它们可以完全实现。只有在实现位置时我们才需要所有的孩子。

另一种解决方法是将部分位置信息实现为匿名类型。这允许您获取有关ChildLocations的Location和某些的信息,而不违反实例只能以完整形式实现的规则。由于您实际上没有实现真正的位置,因此无需实现整个事物:

from Locations in this.LocationDataContext.Locations
where Locations.LocationType.ID == 3
select new 
{
    ID = Locations.ID,
    LocationType= Locations.LocationType
    ChildLocations = from ChildLocation in Locations 
                     where ChildLocation.LocationType.ID == 2
                     select ChildLocation
}