2012-02-15 32 views
5

Tôi có hai bảng sau:NHibernate - Left tham gia

Jobs AreaID, JobNo (key composite)

Logs LogID, AreaID, JobNo

tôi cần để có được tất cả các việc làm không có bất kỳ nhật ký nào được liên kết với chúng. Trong SQL tôi có thể làm:

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 

Nhưng tôi không chắc chắn làm thế nào để thực hiện điều này với NHibernate. Bất cứ ai có thể cung cấp bất kỳ con trỏ?

Dưới đây là ánh xạ của tôi:

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

Cảm ơn

Cập nhật

OK, tôi sửa đổi Nosila của câu trả lời hơi, và điều này đang làm những gì tôi muốn:

Log logs = null; 

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

Tôi cũng phải thêm công việc này vào công việc của mình ánh xạ:

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

Cảm ơn sự giúp đỡ. :)

+0

Bạn có thể đăng truy vấn bạn có ngay bây giờ không? – Nosila

+0

Truy vấn SQL ở trên hiện đang là những gì tôi đang sử dụng. Tôi chỉ đang học NH vào lúc này và đang cố gắng chuyển đổi một ứng dụng nhỏ sang sử dụng nó. – Tom

+0

Bạn đã tạo bản đồ chưa? Ngoài ra, ai đó sửa tôi nếu tôi sai nhưng tôi nghĩ rằng bạn cần NHibernate 3.2 để thêm điều kiện để tham gia của bạn (sử dụng API 'QueryOver', anyways). – Nosila

Trả lời

6

Tôi không quen thuộc với số nhận dạng tổng hợp vì tôi không sử dụng chúng vì vậy tất cả tôi biết NHibernate sẽ tự động tạo tham gia thích hợp bên trái. Không ít, truy vấn (không được kiểm tra) bên dưới sẽ giúp bạn bắt đầu.

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

Lưu ý: Bạn cần NHibernate 3.2 để đặt điều kiện tham gia.

+1

Cảm ơn. Tôi sẽ phải nghiền ngẫm cái này (có một vài lỗi trong đó). Nó cũng có vẻ cực kỳ phức tạp cho một truy vấn đơn giản như vậy. – Tom

+0

@Tom Tôi đồng ý với sự phức tạp, viết điều này trong SQL sẽ đơn giản hơn nhiều. Tôi cảm thấy sự trừu tượng ORM đang thoát ra khỏi tầm tay. – Jafin

4
Job job = null; 
var jobsWithoutLogs = session.QueryOver(() => job) 
    .WithSubquery.WhereNotExists(QueryOver.Of<Log>() 
     .Where(log => log.Job == job) 
     .Select(Projections.Id())) 
    .List() 

Cập nhật: tôi thấy bạn đã thêm ánh xạ. Mã trên chỉ hoạt động cho các bản đồ sau đây

<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

Rất đẹp. Tôi thích giải pháp này tốt hơn. – Nosila

+0

Điều này có vẻ dễ dàng hơn, mặc dù tôi nhận được lỗi "Không thể sử dụng truy vấn con trên tiêu chí không có phép chiếu". Ngoài ra, đây có phải là một truy vấn đắt tiền hơn vì nó sử dụng các truy vấn phụ thay vì một phép nối đơn giản bên trái không? – Tom

+0

1) đã thêm phép chiếu. 2) tôi không nghĩ rằng nó đắt hơn kể từ khi làm điều tương tự. bạn có thể kiểm tra kế hoạch truy vấn – Firo

Các vấn đề liên quan