Как вы lazy загружаете вложенные списки без фактического выполнения запроса? Используя очень простой пример, скажем, у меня есть: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 владельцев блоков, а около 1000000 городских блоков, загрузка всех из них не является вариантом. Использование IQueryables не будет работать из-за гнездования (без особого взлома, по крайней мере, я знаю). Кроме того, если я попытаюсь использовать что-то вроде LazyList Rob Conery, то у нас по существу есть утечка из нашего DAL в наши модели домена, что может быть очень и очень плохо в будущем.
Итак, как мне сделать это правильно?
- Вопрос об определении правильного контекста ? Если да, будем ли мы делать в слое репозитория или на уровне сервиса ?
- Я получу общий уровень обслуживания и уровень моего хранилища, чтобы получить очень специфические методы обслуживания?
- Или я чего-то не хватает? (Все еще относительно новое для Linq2Sql вещь, которая постепенно сокращается в любом случае, так ...)
Edit: В хранилище шаблон, мы в настоящее время отображение наших объектов предметной области, так это будет выглядеть примерно так:
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 объект в IQueryable - который не делает кажется правильным, потому что кажется, что слишком много власти будет предоставлено любому, кто обратится к Cit Поле yBlock.BuildingsOnBlock. Является ли это сопоставление нашим объектам домена чем-то, что мы, возможно, должны делать на уровне сервиса?
Вся фаза-аут, что это отвлекающий маневр. Хотя это правда, что он не собирается уделять много внимания с точки зрения улучшений, он уже находится в рамках, поэтому он будет с нами некоторое время. В любом случае, StackOverflow использует Linq для SQL, и я бы сказал, что он работает очень хорошо. –
Что вы возвращаете из своего метода GetCityBlocks()? Поскольку вы используете фильтры расширений, я думаю, вы уже возвращаете IQueryable правильно? иначе вы действительно должны использовать ответ Роберта для этого. Обратите внимание, что публикация IQueryable из вашего репозитория означает только предоставление Linq не Linq2Sql – Jaime