如何在不实际执行查询的情况下延迟加载嵌套列表?使用非常简单的例子,说我有:Linq2Sql - 你如何延迟加载嵌套列表?
class CityBlock {
IList<Building> BuildingsOnBlock;
Person BlockOwner;
}
class Building {
IList<Floor> FloorsInBuilding;
}
class Floor {
IList<Cubicle> EmployeeCubicles;
}
Class Cubicle {
System.Guid CubicleID;
Person CubicleOccupant;
}
然后在我的仓库层,我有以下方法:
GetCityBlocks()
然后在服务层我要GetCityBlocksByOwner,其中我使用的扩展方法来获得特定的人所拥有的城市街区,说我们只想圭多的块:
GetCityBlocks().ForOwner("Guido")
如果我们做一个.ToList()在仓库中它要执行查询 - 这将是荒谬的,因为我们不知道我们在那个级别获得的块是谁。所以问题是,我们如何有效地做到这一点?
假设有50000个街区所有者和100万个城市街区,加载它们不是一个选项。使用IQueryables将无法工作,因为嵌套(没有极端黑客攻击,至少我知道)。此外,如果我尝试使用Rob Conery的LazyList之类的东西,那么我们基本上会从我们的DAL泄漏到我们的域模型中,这可能在未来非常糟糕。
那么我该如何正确地做到这一点?
- 难道是确定 正确的上下文吗?如果是这样,我们会在存储库层还是 服务层执行 ?
- 我是否将服务层和我的存储库层合并在一起,以获得非常具体的服务方法 ?
- 或者我完全错过了一些东西? (还是相对较新的LINQ2SQL 的事情,这将被淘汰 反正所以...)
编辑: 在存储库模式,我们目前映射到我们的域对象,所以它会是这个样子:
public IQueryable<CityBlock> GetCityBlocks(){
var results = from o in db.city_blocks
let buildings = GetBuildingsOnBlock(o.block_id)
select new CityBlock {
BuildingsOnBlock = buildings,
BlockOwner = o.block_owner
};
return results;
}
对于这项工作,我们不得不使建筑得到.ToList(),除非我们做的是,在实际CityBlock Field对象为IQueryable - 这不看起来是正确的,因为看起来任何访问Cit的人都有太多的权力yBlock.BuildingsOnBlock字段。这是映射到我们的域对象的东西,我们应该可能做的服务层?
整体淘汰的是一个红色的鲱鱼上。诚然,它不会在改进方面得到太多关注,但它已经在框架中,所以它会与我们在一段时间。无论如何,StackOverflow使用Linq to SQL,我会说它工作得很好。 – 2009-08-13 23:49:03
你从GetCityBlocks()方法返回什么?既然你使用扩展过滤器,我猜你已经返回IQueryable了吗?否则你真的应该使用罗伯特的答案。请注意,从存储库中公开IQueryable意味着只公开Linq而不是Linq2Sql – Jaime 2009-08-14 00:09:58