Собственность коллекции NHibernate из запроса (не свободно) - PullRequest
0 голосов
/ 24 апреля 2018

Возможно ли иметь коллекцию только для чтения на объекте, где коллекция заполняется пользовательским запросом SQL?

У меня есть 3 класса - Village, Report и Army - каждый из которых поддерживается таблицей. Я хочу, чтобы у Village было свойство "ReportsAsDefender", которое представляет собой коллекцию Reports, в которой защищающийся Army в этом Report принадлежит данному Village:

SELECT
    village.Id as VillageId, report.*
FROM
    armies army

    join reports report
        on report.DefendingArmyId = army.Id
    join villages village
        on village.Id = army.VillageId 

Я хочу, чтобы результаты этого запроса были доступны в виде коллекции в моем классе Village. Это может быть выполнено с использованием только сопоставления XML, но я не могу найти ничего полезного здесь.

Я не использую Fluent.


Редактировать 1: Я загрузил свой текущий исходный код и пример данных SQL, чтобы мои проблемы можно было воспроизвести: https://github.com/tylercamp/NHTW

Я также обновил SQL-запрос выше, чтобы соответствовать моим текущим изменениям.

С изменениями, предложенными @ RadimKöhler, я получаю исключение при вызове someVillage.ReportsAsDefender.ToList(): could not initialize a collection:, за которым следует бессмысленный MySQL:

SELECT
    reportsasd0_.VillageId as villageid11_4_1_,
    reportsasd0_.Id as id1_4_1_,
    reportsasd0_.Id as id1_4_0_,
    reportsasd0_.TribalWarsId as tribalwarsid2_4_0_,
    reportsasd0_.WorldId as worldid3_4_0_,
    --- ... and a for more nonsensical "selects"

FROM Reports reportsasd0_ WHERE reportsasd0_.VillageId=?

У меня нет ни малейшего понятия, откуда взято "asd", и нет никакого другого форматирования. Строка «asd» нигде не отображается в моей кодовой базе.

Соответствующие сущности из моего файла .hbm.xml содержат:

  <class name="Village" table="Villages">
    <id name="Id">
      <generator class="increment" />
    </id>

    <property name="TribalWarsId" />
    <property name="WorldId" />
    <property name="Name" />
    <property name="OwnerId" />

    <!-- Where "villa_reports_as_defender" is the name of the view query shown above -->
    <bag name="ReportsAsDefender" table="villa_reports_as_defender" mutable="false" lazy="true" inverse="true">
      <key column="VillageId" />
      <one-to-many class="Report"/>
    </bag>
  </class>

  <!-- Report -->
  <class name="Report" table="Reports">
    <id name="Id">
      <generator class="increment" />
    </id>

    <property name="TribalWarsId" />
    <property name="WorldId" />

    <property name="AttackingArmyId" />
    <property name="DefendingArmyId" />
    <property name="RemainingAttackingArmyId" />
    <property name="RemainingDefendingArmyId" />
    <property name="DodgedArmyId" />

    <property name="OccurredAt" />
    <property name="LaunchedAt" />
  </class>

Мой Village класс имеет следующее свойство:

public virtual ICollection<Report> ReportsAsDefender { get; set; }

1 Ответ

0 голосов
/ 26 апреля 2018

Любые связанные данные должны отображаться как стандартная сущность . Даже если это будет представление (вопрос может заключаться в том, насколько эффективной будет загрузка данных ...)

Такое представление должно иметь столбец отношения (например, Parent_ID). Это может быть выражено как много-к-одному в дочернем отображении:

<many-to-one name="Parent" column="Parent_ID" ... />

и именно этот столбец мы должны использовать в родительском отображении

<bag name="Children"
       lazy="true" 
       inverse="true" 
       batch-size="25" 
       cascade="all-delete-orphan" >
    // This columns is the same as for many-to-one
    <key column="Parent_ID" />
    <one-to-many class="Child" />
</bag>

Проверьте все детали здесь:

Минимальный и правильный способ сопоставления «один ко многим» с помощью NHibernate

...