2011-12-28 4 views
2

Существует сущность усилию, который имеет свойство Список и свойство AdType У нас есть несколько AdTypes перечисляемые объекты и specialLists объектов, перечислений выбрать IList<Effort>NHibernate QueryOver на протяжении многих таблиц

Я делаю это следующим образом:

return NHibernateSession.QueryOver<Effort>() 
     .JoinQueryOver(effort => effort.AdType) 
       .WhereRestrictionOn(adType => adType.Id) 
       .IsIn(adTypes.Select(adt => (long)adt).ToList()) 
      .Clone() 
      .JoinQueryOver(effort => effort.List) 
       .WhereRestrictionOn(list => list.Id) 
       .IsIn(specialLists.Select(sl => (long)sl).ToList()) 
      .List<Effort>(); 

как можно видеть. Я использую странный метод Clone(), который не имеет никакого описания. Он отлично работает.

Каким образом вы используете QueryOver для таких запросов?

+1

Мне интересно здесь то, что происходит, если опустить клон, также, что SQL запускаемое из к базе данных? – Rippo

+0

Без Clone() он не будет пытаться выполнить следующие команды Join to Effort. Он попытается сделать это с AdType. Так что не будет .JoinQueryOver (effort => effort.List) будет .JoinQueryOver (adType => adType .....) – Anubis

ответ

6

.JoinQueryOver(effort => effort.AdType) вернет QueryOver с подтипом, здесь AdTypeIQueryOver<Effort, Adtype> вместо оригинала IQueryOver<Effort, Effort>. Первый общий аргумент - это queryType, а второй тип, на котором работают методы. Если вы клонируете между целым запросом, он копируется и возвращается как базовый запрос IQueryOver<Effort, Effort>.

Чтобы запретить QueryOver переключаться на подтип, существует JoinAlias, который создает псевдоним вместо нисходящего.

AdType adAlias = null; 
ListType listAlias = null; 

return NHibernateSession.QueryOver<Effort>() 
    .JoinAlias(effort => effort.AdType,() => adAlias) 
    .JoinAlias(effort => effort.List,() => listAlias) 
    .WhereRestrictionOn(() => adAlias.Id).IsIn(adTypes.Cast<long>().ToList()) 
    .WhereRestrictionOn(() => listAlias.Id).IsIn(specialLists.Cast<long>().ToList()) 
    .List<Effort>(); 

не то, что если вы Ограничить только идентификатор adtype и listtype затем

return NHibernateSession.QueryOver<Effort>() 
    .WhereRestrictionOn(effort => effort.Adtype.Id).IsIn(adTypes.Cast<long>().ToList()) 
    .WhereRestrictionOn(effort => effort.List.Id).IsIn(specialLists.Cast<long>().ToList()) 
    .List<Effort>();