Свободный NHibernate: Как я могу написать этот запрос в качестве критерия? - PullRequest
3 голосов
/ 28 апреля 2011

Структура данных следующая: в доме много комнат.В каждой комнате много людей.

Что я хочу сделать, так это собрать всех людей для дома.В простом 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);

Физическое лицо

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

Персональное отображение

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

1 Ответ

5 голосов
/ 28 апреля 2011

Чтобы приблизить 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...