流利的NHibernate:我如何将此查询作为标准编写?

Awe*_*ome 3 sql fluent-nhibernate

数据结构如下:房子有很多房间.每个房间都有很多人.

我想做的是让所有人都入住.在纯SQL中我会写以下内容:

SELECT * FROM Person WHERE Room_id
IN
(SELECT Id FROM Room WHERE House_id = 1)
Run Code Online (Sandbox Code Playgroud)

我怎么能用Fluent NHibernate'ish代码写出来?

对于此示例,我们可以假设实体和映射看起来像这样:

众议院实体

public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IEnumerable<Room> Rooms { get; set; }
Run Code Online (Sandbox Code Playgroud)

房子映射

Id(x => x.Id);
Map(x => x.Name);
HasMany(x => x.Rooms);
Run Code Online (Sandbox Code Playgroud)

房间实体

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; }
Run Code Online (Sandbox Code Playgroud)

房间地图

Id(x => x.Id);
Map(x => x.Name);
References(x => x.House);
HasMany(x => x.Persons);
Run Code Online (Sandbox Code Playgroud)

人实体

public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Room Room { get; set; }
Run Code Online (Sandbox Code Playgroud)

人物映射

Id(x => x.Id);
Map(x => x.Name);
References(x => x.Room);
Run Code Online (Sandbox Code Playgroud)

Jak*_*art 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>();
Run Code Online (Sandbox Code Playgroud)

这产生了这样的东西:

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
Run Code Online (Sandbox Code Playgroud)

我在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>();
Run Code Online (Sandbox Code Playgroud)

它产生不同的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
Run Code Online (Sandbox Code Playgroud)