2011-04-28 40 views
3

數據結構如下: 房子有很多房間。每個房間都有很多人。流利的NHibernate:我如何將這個查詢作爲條件來編寫?

我想要做的就是讓所有人都住一間房子。在普通的SQL中,我會寫出以下內容:

SELECT * FROM Person WHERE Room_id 
IN 
(SELECT Id FROM Room WHERE House_id = 1) 

如何在Fluent NHibernate'ish代碼中編寫該代碼?

在這個例子中,我們可以假設實體和映射是這樣的:

家實體

public virtual int Id { get; set; } 
public virtual string Name { get; set; } 
public virtual IEnumerable<Room> Rooms { get; set; } 

家測繪

Id(x => x.Id); 
Map(x => x.Name); 
HasMany(x => x.Rooms); 

間實體

public virtual int Id { get; set; } 
public virtual string Name { get; set; } 
public virtual House House { get; set; } 
public virtual IEnumerable<Person> Persons { get; set; } 

間映射

Id(x => x.Id); 
Map(x => x.Name); 
References(x => x.House); 
HasMany(x => x.Persons); 

Person實體

public virtual int Id { get; set; } 
public virtual string Name { get; set; } 
public virtual Room Room { get; set; } 

Person的映射

Id(x => x.Id); 
Map(x => x.Name); 
References(x => x.Room); 
+0

這不是一個問題,通順 - 通順只對指定的映射和配置。根據您使用的NHibernate版本,您可以選擇HQL,Criteria API或(如果是NH3)Linq。 – UpTheCreek 2011-04-28 08:55:59

+0

請問,你能展示你的實體和映射嗎? – 2011-04-28 09:30:32

+0

@Jakub:完成。 @UpTheCreek:哪個解決方案看起來最漂亮?你可以給我一個例子嗎? – Awesome 2011-04-28 10:31:05

回答

5

,收穫得SQL查詢到你的,你可以使用這些標準:

var subCriteria = DetachedCriteria.For<Room>(); // subquery 
subCriteria.Add(Expression.Eq("House", house)); // where clause in subquery 
subCriteria.SetProjection(Projections.Id()); // DetachedCriteria needs to have a projection, id of Room is projected here 

var criteria = session.CreateCriteria<Person>(); 
criteria.Add(Subqueries.PropertyIn("Room", subCriteria)); // in operator to search in detached criteria 
var result = criteria.List<Person>(); 

這將產生某物像這樣:

SELECT this_.Id as Id4_0_, this_.Name as Name4_0_, this_.RoomId as RoomId4_0_ 
FROM [Person] this_ 
WHERE this_.RoomId in (SELECT this_0_.Id as y0_ FROM [Room] this_0_ WHERE this_0_.HouseId = @p0)',N'@p0 int',@p0=1 

我測試了它在FNH1.2和NH3.1但應NH2.1中發揮作用。編輯: UpTheCreek是正確的。 Linq比Criteria API更清晰。例如:

var query = session.Query<Person>().Where(x => x.Room.House == house); 
var linqResult = query.ToList<Person>(); 

產生不同的SQL查詢,但結果集是一樣的:

select person0_.Id as Id4_, person0_.Name as Name4_, person0_.Room_id as Room3_4_ 
from [Person] person0_, [Room] room1_ 
where person0_.Room_id=room1_.Id and room1_.House_id=2 
+0

這個作品真的很不錯!感謝您的幫助,Jakub! – Awesome 2011-04-28 11:35:07

+0

我很高興它有幫助。但UpTheCreek是正確的。 Linq比我個人討厭的標準API更清晰:)。在另一方 方面我對NH Linq很謹慎,因爲歷史原因 - NH2.1中的Linq實現並不是非常有用。但自己判斷 (編輯帖子)。 – 2011-04-28 11:53:55