NHibernate - левые соединения - PullRequest
       30

NHibernate - левые соединения

6 голосов
/ 15 февраля 2012

У меня есть следующие две таблицы:

Задания AreaID, JobNo (составной ключ)

Журналы LogID, AreaID, JobNo

Мне нужно получить все задания, с которыми не связаны журналы. В SQL я мог бы сделать:

SELECT Jobs.AreaID,
       Jobs.JobNo
FROM   Jobs
       LEFT JOIN Logs
           ON Jobs.AreaID = Logs.AreaID
           AND Jobs.JobNo = Logs.JobNo
WHERE  Logs.LogID is null

Но я не уверен, как этого добиться с помощью NHibernate. Может ли кто-нибудь предложить какие-либо указатели?

Вот мои отображения:

<class name="Job" table="Jobs">
    <composite-key name="Id">
        <key-property name="JobNo"/>
        <key-many-to-one name="Area" class="Area" column="AreaID"/>
    </composite-key>
</class>

<class name="Log" table="Logs">
    <id name="Id" column="LogID">
        <generator class="identity"/>
    </id>
    <property name="JobNo"/>
    <many-to-one name="Area" class="Area" column="AreaID"/>
</class>

Спасибо

Обновление

ОК, я слегка изменил ответ Носилы, и теперь он делает то, что хотел:

Log logs = null;

return session.QueryOver<Job>()
    .Left.JoinAlias(x => x.Logs, () => logs)
    .Where(x => logs.Id == null)
    .List<Job>();

Я также должен был добавить это в мое отображение работы:

<bag name="Logs">
    <key>
        <column name="JobNo"></column>
        <column name="DivisionID"></column>
    </key>
    <one-to-many class="Log"/>
</bag>

Спасибо за помощь. :)

Ответы [ 2 ]

6 голосов
/ 15 февраля 2012

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

Job jobAlias = null;
Log logAlias = null;
YourDto yourDto = null;

session.QueryOver<Job>()
    // Here is where we set what columns we want to project (e.g. select)
    .SelectList(x => x
        .Select(x => x.AreaID).WithAlias(() => jobAlias.AreaID)
        .Select(x => x.JobNo).WithAlias(() => jobAlias.JobNo)
    )
    .Left.JoinAlias(x => x.Logs, () => logAlias, x.JobNo == logAlias.JobNo)
    .Where(() => logAlias.LogID == null)
    // This is where NHibernate will transform what you have in your `SelectList()` to a list of objects
    .TransformUsing(Transformers.AliasToBean<YourDto>())
    .List<YourDto>();

public class YourDto
{
    public int AreaID { get; set; }
    public int JobNo { get; set; }
}

Примечание. Чтобы настроить условия соединения, необходим NHibernate 3.2.

4 голосов
/ 15 февраля 2012
Job job = null;
var jobsWithoutLogs = session.QueryOver(() => job)
    .WithSubquery.WhereNotExists(QueryOver.Of<Log>()
        .Where(log => log.Job == job)
        .Select(Projections.Id()))
    .List()

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

<class name="Log" table="Logs">
    <id name="Id" column="LogID">
        <generator class="identity"/>
    </id>
    <many-to-one name="Job" >
      <column name="JobNo"/>
      <column name="AreaID"/>
    <many-to-one />
</class>
...