2012-02-15 1 views
5

나는 다음과 같은 두 개의 테이블이 있습니다NHibernate에 - 왼쪽 조인

채용 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 함께이 작업을 수행할지 모르겠습니다. 아무도 어떤 포인터를 제공 할 수 있습니까? 여기

내 매핑은 다음과 같습니다

OK

<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> 

감사

업데이트, 나는 약간 Nosila의 답변을 수정, 이것은 지금 내가 원하는 일을한다 :

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> 

도움 주셔서 감사합니다. :)

+0

지금 질문을 게시 할 수 있습니까? – Nosila

+0

위의 SQL 쿼리는 현재 내가 사용하고있는 것입니다. 나는 지금 NH를 배우고 있으며 작은 응용 프로그램을 그것을 사용하도록 변환하려고합니다. – Tom

+0

매핑이 생성 되었습니까? 또한, 만약 내가 틀렸다면 누군가가 나를 바로 잡는다.하지만 당신은 조인에 조건을 추가하기 위해 (QueryOver API를 사용하여, 어쨌든) NHibernate 3.2가 필요하다고 생각한다. – Nosila

답변

6

나는 이것들을 사용하지 않기 때문에 합성 식별자에 익숙하지 않다. 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가 필요합니다.

+1

. 이 문제에 대해 궁금해 할 것입니다 (몇 가지 오류가 있습니다). 또한 이러한 간단한 쿼리에는 매우 복잡한 것처럼 보입니다. – Tom

+0

@Tom 나는 복잡성에 동의한다. SQL로 작성하는 것이 훨씬 간단하다. ORM 추상화가 손에 닿기 시작했다. – Jafin

4
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> 
+0

니스. 나는이 해결책을 더 좋아한다. – Nosila

+0

"투영없이 조건에 서브 쿼리를 사용할 수 없다"라는 오류가 발생하더라도이 방법은 더 쉬워 보입니다. 또한 단순한 왼쪽 조인 대신 하위 쿼리를 사용하기 때문에 이것은 더 비싼 쿼리가 될 것입니까? – Tom

+0

1) 투영이 추가되었습니다. 2) 나는 그 일을 한 이후로 더 비싸다고 생각하지 않는다. 당신은 쿼리 계획을 확인할 수 – Firo