2012-01-06 5 views
0

Можно ли сделать левое соединение, но заказать столбец в правой таблице с помощью hql?Nhibernate, HQL left join order by right table column

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

public class SomeDocument 
{ 
    public virtual int Id { get; set; } 
    public virtual DocumentPart Part1 { get; set; } 
    public virtual DocumentPart Part2 { get; set; } 
} 

public class DocumentPart 
{ 
    public virtual int Id { get; set; } 
    public virtual string Content { get; set; } 
} 

part1 и part2 свойство обнуляемое.

SQL:

create table SomeDocument 
    (
    Id number(*, 0) not null, 
    DocumentPart1_ID NUMBER, 
    DocumentPart2_ID NUMBER 
); 

create table DocumentPart 
    (
    Id number(*, 0) not null, 
    Content nvarchar2(250) not null 
); 

Mapping:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Testapp.domain" namespace="Testapp.domain.model"> 
    <class name='SomeDocument' table='SomeDocument' lazy="false"> 
    <many-to-one name='Part1' class="Testapp.domain.model.DocumentPart, Testapp.domain" lazy="false" column='DocumentPart1_ID' cascade="save-update" /> 
    <many-to-one name='Part1' class="Testapp.domain.model.DocumentPart, Testapp.domain" lazy="false" column='DocumentPart2_ID' cascade="save-update" /> 
    </class> 
</hibernate-mapping> 

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Testapp.domain" namespace="Testapp.domain.model"> 
    <class name='DocumentPart' table='DocumentPart' lazy="false"> 
    <property name='Content' column='Content' not-null="true"/> 
    </class> 
</hibernate-mapping> 

и теперь, если я пытаюсь заказать SomeDocuments по Part1.Content:

UnitOfWork.CurrentSession 
      .CreateQuery("from SomeDocument doc order by doc.Part1.Content") 
      .List<SomeDocument>(); 

я буду получать только те строки, где не является нулевым , NHibernate будет генерировать SQL как это:

select * from 
SomeDocument doc, 
DocumentPart docPart, 
where doc.DocumentPart1_ID = docPart.Id 
order by docPart.Content 

но то, что я хочу что-то вроде этого:

select * from 
SomeDocument doc 
left join DocumentPart docPart on doc.DocumentPart1_ID = docPart.Id 
order by docPart.Content 

Моя база данных Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64-разрядные

ответ

1

Явным образом укажите, что вы хотите левое соединение в запросе.

select doc from SomeDocument doc left join doc.Part1 part order by part.Content 

Если оставить из select doc из запроса, NHibernate будут выбраны все объекты, в данном случае это было бы эквивалентно написанию select doc, part. Это создало бы результирующий набор типа object[], который представляет кортеж SomeDocument, DocumentPart.

+0

ty сэр. добавление «select doc» в строку запроса устраняет проблему. – shkipper

+0

Серьезно, мне приходится вручную выписывать объединения каждый раз? нет способа настроить это в сопоставлениях? Хлоп. –

+0

Обычно вы можете настроить его на использование левого левого соединения, но в этом вопросе я не уверен, каким будет результат, так как 'a.b.c' стремится создать внутреннее соединение от a до b. Также вы, вероятно, получите дубликаты в результате, если вы не используете что-то вроде Transformers.DistinctRootEntity –