NHibernate имеет одну ленивую нагрузку - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть отношение родитель-потомок, на Sql Server только один дочерний элемент. Ребенок содержит толстые данные, которые я не загружу. Ребенок является необязательным, и это должно зависеть от жизненного цикла родителя. Таким образом, внешний ключ дочернего элемента указывает на родительский элемент и является уникальным.

Я могу использовать официальный пример в Hibernate.

public class Phone
{
    public virtual long Id { get; set; }

    public virtual string Number { get; set; }

    public virtual PhoneDetails Details { get; set; }
}

public class PhoneDetails
{
    public virtual int Id { get; set; }

    public virtual Phone Phone { get; set; }

    public virtual string Provider { get; set; }
}

Данные телефона должны зависеть от жизненного цикла родителя в базе данных. Я могу использовать отношение «один к одному» в SQL с уникальным внешним ключом для дочернего элемента или отношение «один к одному» с простым внешним ключом (как в примере) плюс уникальное ограничение.

CREATE TABLE Phone (
    id BIGINT IDENTITY PRIMARY KEY,
    number VARCHAR(255)
)

CREATE TABLE PhoneDetails (
    id BIGINT IDENTITY PRIMARY KEY,
    phone_id BIGINT UNIQUE FOREIGN KEY REFERENCES dbo.Phone(id),
    provider VARCHAR(255)        
)

И это нормально, я думаю:

enter image description here

Итак, у меня есть телефон, он может жить без деталей, и когда мне нужно, я могу добавить только одну деталь, чтобы дополнить свой объект другими деталями, которые я не хочу загружать всегда.

Как я могу отобразить эти классы на NHibernate 5? Кажется, мне нужно использовать HasOne в двух направлениях, но в этом случае я не могу использовать ленивую загрузку, поэтому каждый простой запрос на телефоне приведет к объединению и выбору всех полей деталей.

Я использую таблицу сведений для хранения огромных метаданных, которые мне не нужны в 90% времени, но теперь везде, где я пытаюсь загрузить телефон, запрос загружает также огромные детали, это действительно плохо.

Так каким образом я могу отобразить это отношение?

Родитель и один ребенок, содержащий бесполезные жирные данные. В sql я думаю, что структура в порядке, потому что я не хочу больше детей, и я хочу, чтобы они жили под родителем (так что FK на ребенка).

Невозможно, чтобы не управлялись такого рода отношениями, где я не прав? дизайн базы данных? отображение

Это отображение, которое я использую:

  <class name="Phone" table="Phone">
    <id name="Id">
      <generator class="native"/>
    </id>
    <property name="Number"/>
    <one-to-one name="PhoneDetails" class="PhoneDetails"/>
  </class>

  <class name="PhoneDetails" table="PhoneDetails">
    <id name="Id">
      <generator class="native"/>
    </id>
    <property name="Provider" />
    <many-to-one name="Phone" column="phone_id" unique="true"/>    
  </class>

Я также пытался со вторыми вариантами использовать внешний \ первичный ключ в реляционной модели (поэтому я удалил FK и использовал тот же Id, что и PK \ FK) с этим отображением в дочернем:

   <one-to-one name="Phone" class="Phone" constrained="true" />

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

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

Итак, чтобы обойти это, почему бы вам не избавиться от этих отношений один на один? Если вам не нужны подробности в 90% случаев, я хотел бы рассмотреть вопрос об удалении реляционного корабля и иметь отдельный метод хранилища, который просто позволяет вам получить PhoneDetails для указанного Phone.

Чтобы продолжить ваш пример, я бы закончил с этим:

public class Phone
{
    public virtual long Id { get; set; }

    public virtual string Number { get; set; }
}

public class PhoneDetails
{
    public virtual int Id { get; set; }

    public virtual Phone BelongsToPhone { get; set; }

    public virtual string Provider { get; set; }
}

public class PhoneRepository
{
      public Phone GetPhone( long id ){}

      public PhoneDetails GetPhoneDetails( Phone phone ){}
}
0 голосов
/ 05 сентября 2018

Обнуляемый один-к-одному не может знать, не запрашивая ассоциированную таблицу, существует ли она или нет, поэтому для загрузки своего прокси-сервера требуется запросить ассоциированную таблицу. С этого момента, как известно, в прошлых обсуждениях считалось, что лучше запрашивать все состояние, а не только ключ, то есть нагрузку. -> Вы не сможете включить отложенную загрузку для ссылки, которая не является обязательной. По крайней мере, не со стандартным решением.

Если вы хотите, чтобы отношение могло лениво загружать PhoneDetails, вам придется сделать его обязательным / не обнуляемым.

В качестве альтернативы вы можете пометить свойства в PhoneDetails как lazy="true". Поэтому к таблице будет получен доступ, и для объекта PhoneDetail будет создан прокси, как только вы загрузите родительский объект, но все свойства, отмеченные как lazy="true", будут загружены только после того, как вы к ним получите доступ. Обратите внимание, что ВСЕ свойства с lazy="true" будут загружены, как только вы перейдете к одному из них

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...