Внутреннее соединение NHibernate дает ожидаемый путь для соединения

У меня есть три таблицы:

- Person
- User
- PersonSecret

где PersonSecret ссылка на Person и User:

<class name="PersonSecret" table="PersonSecret" lazy="false"  >
<id name="Id" column="Id" type="Guid">      
                <generator class="assigned"/>
</id>
...
<many-to-one  name="Person" class="Person" foreign-key="FK_Person_PersonSecret" lazy="proxy" fetch="select">
    <column name="PersonId"/>
</many-to-one>
<many-to-one  name="User" class="User" foreign-key="FK_User_PersonSecret" lazy="proxy" fetch="select">
    <column name="UserId"/>
</many-to-one>

This is the mapping from User to PersonSecret:

<set name="PersonSecrets" lazy="true" inverse="true" cascade="save-update" >
<key>
    <column name="UserId"/>
</key>
<one-to-many class="PersonSecret"/>

And this from Person to PersonSecret:

<set name="PersonSecrets" lazy="true" inverse="true" cascade="save-update" >
<key>
    <column name="PersonId"/>
</key>
<one-to-many class="PersonSecret"/>

Now, i try to select all Persons, which has a Entry in PersonSecret for a specific User:

var query = this.Session.CreateQuery(@"from Person a inner join PersonSecret b 
          where b.UserId = :userId and b.RemindeBirthday = :remind");

Это дает мне теперь ExceptionMessage: «Путь, ожидаемый для присоединения»

Может кто-нибудь помочь мне, что я делаю неправильно? - Спасибо.


person BennoDual    schedule 29.06.2011    source источник


Ответы (2)


Есть несколько проблем с вашим запросом HQL:

  • При использовании HQL вам необходимо ссылаться на имена свойств классов вашей модели вместо имен столбцов, с которыми они сопоставляются. В этом случае вы должны ссылаться на свойство PersonSecret.User.Id в предложении where, а не на столбец UserId.
  • Вы также должны указать свойство Person.PersonSecrets в предложении соединения, иначе NHibernate не будет знать, какие столбцы объединять.
  • Вы должны указать дополнительный фильтр как условие соединения, используя ключевое слово with, а не в предложении where.

Вот правильная версия:

var query = this.Session.CreateQuery(
    @"from Person as a inner join a.PersonSecrets as b with b.User.Id = :userId and b.RemindeBirthday = :remind");

Связанные ресурсы:

person Enrico Campidoglio    schedule 29.06.2011
comment
@t.kehl Я немного поторопился с ответом на этот вопрос. Я обновил свой ответ другим решением. - person Enrico Campidoglio; 29.06.2011
comment
@Enrico - Можете ли вы объяснить мне, как это сделать: указать свойство Person.PersonSecrets в предложении соединения? - person BennoDual; 29.06.2011
comment
@t.kehl Я предоставил вам правильную версию запроса в своем ответе. Предложение соединения должно быть from Person as a inner join a.PersonSecrets as b. - person Enrico Campidoglio; 29.06.2011
comment
@Enrico - ах, извините - это работает - я не видел s в PersonSecrets :-) - Теперь понятно, как это работает. - Спасибо большое за помощь. - person BennoDual; 29.06.2011

вы забыли термин "ON".

inner join PersonSecret b ON b.PersonId = a.PersonId
person Anubis    schedule 29.06.2011
comment
HQL не поддерживает синтаксис соединения SQL. - person Enrico Campidoglio; 29.06.2011
comment
затем используйте CreateSQLQuery вместо CreateQuery - person Anubis; 29.06.2011