Проблема с использованием Session.Get <T>в классе nHibernate 2.0 для класса с составным идентификатором. - PullRequest
5 голосов
/ 22 января 2009

У меня проблемы с чем-то, что (я думаю) должно быть простым, но я не могу найти никакой ясной информации.

В сценарии, где у меня есть три таблицы, описывающие домен, где человек может иметь более одной работы:

Person - имеет PersonId, Имя
Job - имеет JobId, JobName
PersonJob - имеет PersonId, JobId, YearsOfEmployment

Примечание. В моей объектной модели у меня есть объекты, представляющие каждую таблицу. У меня есть эта третья сущность, которая представляет отношение человек / работа, поскольку там есть полезные метаданные (YearsOfEmployment), а не просто таблица соединения.

Итак, если бы я знал PersonId и JobId, есть ли для меня простой способ использовать сеанс и вернуть объект, соответствующий этим идентификаторам?

Или, другими словами, так как я уже знаю, что первичные ключи - это просто умопомрачительный, простой способ, которым я могу превратить SQL «SELECT YearsOfEmployment FROM PersonJob WHERE PersonId = 1 AND JobId = 1» в нечто вроде 1013 *

var keys = new {PersonId=1, JobId=2};<br> PersonJob obj = Session.Get<PersonJob>(keys);

Кстати: карты будут выглядеть примерно так:

<class name="Person" table="dbo.Person" lazy="true">
  <id name="PersonId">
    <generator class="native"/>
  </id>
  <property name="Name"/>
</class>
<class name="Job" table="dbo.Job" lazy="true">
  <id name="JobId">
    <generator class="native"/>
  </id>
  <property name="JobName"/>
</class>
<class name="PersonJob" table="dbo.PersonJob" lazy="true">
  <composite-id>
    <key-property name="PersonId"></key-property>
    <key-property name="JobId"></key-property>
  </composite-id>
  <property name="YearsOfEmployment"/>
</class>

Ответы [ 2 ]

8 голосов
/ 22 января 2009

Ну, я ответил на свой вопрос. Я думаю, что публикация вашей проблемы почти так же катарсична, как обсуждение ее с кем-то. Если бы я должен был сделать составной идентификатор PersonJob компонентом или классом, то есть

<class name="PersonJob" table="dbo.PersonJob" lazy="true">
    <composite-id name="PersonJobKey" class="PersonJobKey">
      <key-property name="PersonId"></key-property>
      <key-property name="JobId"></key-property>
    </composite-id>
</class>

Тогда я могу просто сделать это:

PersonJobKey key = new PersonJobKey() { PersonId = 1, JobId = 1 };  
PersonJob obj = Session.Get<PersonJob>(key);  
int yearsOfEmployment = obj.YearsOfEmployment;

прохладный. надеюсь, это поможет кому-нибудь еще понять это ...

3 голосов
/ 06 апреля 2009

Спасибо за публикацию ответа выше, я смотрел его на сопоставленном объекте, где у составного ключа нет имени или класса. Когда я попытался создать класс для представления составного ключа, он изменил поведение объекта при использовании другим кодом. Также я хотел написать что-то вроде;

Session.Get<SalesRepArea>(new { AreaCode = "ACode", RegionCode = "RCode"});

Я обнаружил, что nHibernate не может иметь большого смысла в анонимном объекте, но я понял, что мне не нужно имя для моего составного ключа или тип класса. Что такое метод Get nHibernate после, по сути, является временным объектом, так что он может получить свой эквивалентный объект из базы данных (должно быть, поэтому вам нужно переопределить метод equals в вашем классе C #, чтобы заставить работать составной ключ). Так для следующей карты

<class name="SalesRepArea">
   <composite-id>
      <key-property 
         name="AreaCode" column="AreaCode" type="String" length="12" />
      <key-property 
         name="RegionCode" column="RegionCode" type="String" length="12" />
   </composite-id>

Я пишу немного меньше кода и отказываюсь от объекта, представляющего ключ, чтобы получить

SalesRepArea myArea = Session.Get<SalesRepArea>(
   new SalesRepArea()
   { 
      AreaCode = "ACode", 
      RegionCode = "RCode" 
   }
);

Я не говорю, что метод именованного ключа плох, меньше кода не всегда лучше, это просто чтобы показать, что Hibernate ищет объект, в котором находится ключ, чтобы получить конкретный объект из базы данных.

Если я ошибся, пожалуйста, дайте мне знать, но я надеюсь, что это поможет, так как у меня были небольшие проблемы с этим.

Спасибо

Mark

...