2

У меня есть случай, когда мне нужно загрузить около 10 000 объектов из базы данных. Модель данных что-то вроде этого:Как получить объекты нескольких уровней в глубину и ширину с помощью NHibernate?

public class SimulationObject 
{ 
    public Container Container {get;set;} 
    public IList<ResultItem> Results {get;set;} 
    public IList<PreviewData> PreviewData {get;set;} 
    ... 
} 

public class ResultItem 
{ 
    public IList<SomeDataItem> Items {get;set;} 
    ... 
} 

public class PreviewData 
{ 
    public IList<SomeDataItem> Items {get;set;} 
    ... 
} 

Это означает, что я хочу, чтобы запросить список SimulationObjects из базы данных в соответствии с некоторым запросом, и все его свойства (ссылки) и подпункты.

Количество коллекций являются следующим:

  1. SimulationObject - са 6000 - 1200, в зависимости от параметров в "где"
  2. SimulationObject.Results - ч от 5 до 40 пунктов
  3. SimulationObject.Results .Items - CA от 0 до 2 пунктов
  4. SimulationObject.PreviewData - ча от 0 до 2 пунктов
  5. SimulationObject.PreviewData.Items - около 1 до 3 пунктов

Обычно я делаю это так:

var query = from sim in session.Query<SimulationObject>() 
     where sim.Container.Id == containerId && ... 
      select sim; 

query = query.FetchMany(c => c.Results).ThenFetch(o => o.Items)... 

Однако, я также должен принести «PreviewData» пунктов для того что бы создать декартово произведение в моем запросе (то есть количество PreviewDataAndSubItemsCount х ResultsAndSubItemsCount из строки возвращены), что очень неэффективно. Кроме того, поскольку мне нужно загрузить LOT of SumulationObjects (около 10000 как sayd ранее), я не могу выполнять ленивую загрузку (10000 запросов ... и есть и другие трудности, поэтому это даже не альтернатива).

Итак, каковы альтернативы? Какую стратегию вы бы использовали для загрузки графа объектов-компиляторов в память?

Спасибо.

+0

10,000 'SimulationObject' s фирменный номер, или это возможно, что он будет расти в будущем? В среднем, сколько 'ResultItem' за' SimulationObject'? Сколько 'PreviewData' за 'SimulationObject'? Сколько 'SomeDataItem' на' PreviewData' и 'ResultItem'? Вам также нужно получить «SomeDataItem's», или эти внуки могут быть ленивыми? –

+0

В 'SimulationObject', do' PreviewData' и 'ResultItem' делят свои' SomeDataItem''? Другими словами, если задано 'SomeDataItem x', это утверждение истинно:' x.ResultItem.SimulationObject == x.PreviewData.SimulationObject'? Если это так, то у вас есть отношения в форме бриллианта, которые влияют на то, сколько из нас нужно делать на этих объектах внука. –

+0

Нет, они не разделяют отношения. Фактически, элементы PreviewData и элементы ResultItem хранятся в разных таблицах в db. Класс SomeDataItem был псевдокодом. О, и я добавил количества к сообщению. – user315648

ответ

2

Ayende объясняет один из способов сделать это здесь (HQL):
http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate

Был также статья StackOverflow, что я наткнулся, что с помощью QueryOver делает:
NHibernate Eager Loading with Queryover API on a complex object graph

Мне было бы очень интересно получать дополнительный вклад от остальной части сообщества hte. Я думаю, что это одна из областей, в которой NH может улучшиться.

+0

Есть ли способ сделать это с Linq. Я не совсем понимаю этот API QueryOver. Любое хорошее объяснение где-то хотя бы? – user315648

+0

Это не показывает, как это сделать, когда вы хотите получить результаты. Содержимое второго запроса выбрасывается, как указано в сообщении в блоге. Что делать, если вам нужны детские столы с нетерпением. – BradLaney