Стремление загрузить несколько дочерних коллекций в постраничном результате - PullRequest
0 голосов
/ 21 марта 2011

Кажется, я вышел далеко за пределы своих возможностей NHibernate ...

Я пытаюсь загрузить Top10 данного объекта тремя дочерними коллекциями, но реализация Linq от NHibernate дает мне правильные результаты... по стоимости загрузки всей таблицы всех детей.

public class PartnerDto : BaseDto
{
    private IList<EmailContactDto> _emailContacts;
    private IList<TelephoneNumberDto> _telephoneNumbers;
    private IList<string> _chains;
    public EmailContactDto[] EmailContacts
    {
        get { return _emailContacts.ToArray(); }
        set { _emailContacts = value.ToList(); }
    }
    public TelephoneNumberDto[] TelephoneNumbers
    {
        get { return _telephoneNumbers.ToArray(); }
        set { _telephoneNumbers = value.ToList(); }
    }
    public string[] Chains
    {
        get { return _chains.ToArray(); }
        set { _chains = value.ToList(); }
    }
    //more properties
}

Отображение:

<class name="PartnerDto" table="[Partner]" schema-action="none" lazy="false" mutable="false">
<id name="Id">
  <generator class="hilo"/>
</id>
<bag name="Chains" table="PartnerChains" access="field.camelcase-underscore" lazy="false" fetch="subselect">
  <key column="PartnerId"/>
  <element column="Chain" type="System.String"/>
</bag>
<bag name="TelephoneNumbers" access="field.camelcase-underscore" lazy="false" fetch="subselect">
  <key column="PartnerId"/>
  <composite-element class="TelephoneNumberDto">
    <property name="Name" not-null="true"/>
    <property name="ClickToDial" not-null="true"/>
    <property name="SMS" not-null="true"/>
    <property name="Index" column="[Index]" not-null="true"/>
  </composite-element>
</bag>
<bag name="EmailContacts" access="field.camelcase-underscore" lazy="false" fetch="subselect">
  <key column="PartnerId"/>
  <composite-element class="EmailContactDto">
    <property name="Name" not-null="true"/>
    <property name="Email" not-null="true"/>
    <property name="NewsLetter" not-null="true"/>
    <property name="Index" column="[Index]" not-null="true"/>
  </composite-element>
</bag>
<!-- other properties -->

Когда я делаю:

session.Query<PartnerDto>().Take(10);

Я получаю правильные 10 обратно, однако мой sql показывает, что он загружает все строки в таблице TelephoneNumber, EmailContact и PartnerChains вместо того, чтобы ограничивать его 10 загружаемыми партнерами.

Чтоя скучаю?(Да, я должен загрузить все с нетерпением - они должны быть сериализованы сразу после запроса.)

РЕДАКТИРОВАТЬ: найдено решение:

Я сначала запрашиваю только идентификаторы из выгружаемого запроса- тогда я запрашиваю полный граф объекта, используя эти идентификаторы.Поскольку Top 10 теперь находится в предложении where, он используется NHibernate для фильтрации коллекций.Да, он не идеален - у меня есть два обращения и всего пять запросов, но на данный момент мой лучший вариант.

Ответы [ 2 ]

1 голос
/ 21 марта 2011

Используйте batch-size в своих коллекциях с тем же счетчиком, что и размер страницы, и удалите lazy= "false"

. Для получения каждого типа коллекции будет использоваться один запрос.

ЭтоСамый простой способ сделать это и один из самых эффективных.

Конечно, сеанс должен оставаться открытым, пока вы не сериализовали объекты.

0 голосов
/ 21 марта 2011

Я думаю, что проблема не связана с linqtoNH, но является ограничением из-за того, что вы с нетерпением извлекаете коллекцию, это приводит к одному запросу с объединениями, которые не могут быть ранжированы («топ-10»), потому что естьне более отношения один к одному с сущностью записи в исходном наборе результатов, которые поступают из БД.

...