2012-01-25 2 views
2

У меня есть запрос в HQL, который работает хорошо:NHibernate и JoinAlias ​​бросить исключение

var x =_session.CreateQuery("SELECT r FROM NHFolder f JOIN f.DocumentComputedRights r WHERE f.Id = " + rightsHolder.Id + " AND r.OrganisationalUnit.Id=" + person.Id); 
      var right = x.UniqueResult<NHDocumentComputedRight>(); 

В основном я получаю экземпляр NHDocumentComputedRight.

Я попытался реализовать тот же запрос в QueryOver. Я сделал это:

var right = _session.QueryOver<NHFolder>().JoinAlias(b => b.DocumentComputedRights,() => cp).Where(h => h.Id == rightsHolder.Id && cp.OrganisationalUnit.Id == person.Id) 
      .Select(u => cp).List<NHDocumentComputedRight>(); 

Но я получаю исключение для исключения ссылки.

Как я могу реализовать этот запрос в QueryOver?

Update (добавлено отображения) - NHibernate 3,2:

public class FolderMapping: ClassMapping<NHFolder> 
    { 
     public FolderMapping() 
     { 
      Table("Folders"); 
      Id(x => x.Id, map => 
      { 
       map.Generator(IdGeneratorSelector.CreateGenerator()); 
      }); 
//more not important properties... 

      Set(x => x.DocumentComputedRights, v => 
      { 
       v.Table("DocumentComputedRightsFolder"); 
       v.Cascade(Cascade.All | Cascade.DeleteOrphans); 
       v.Fetch(CollectionFetchMode.Subselect); 
       v.Lazy(CollectionLazy.Lazy); 

      }, h => h.ManyToMany()); 


      Version(x => x.Version, map => map.Generated(VersionGeneration.Never)); 
      } 
    } 

public class DocumentComputedRightMapping : ClassMapping<NHDocumentComputedRight> 
    { 
     public DocumentComputedRightMapping() 
     { 
      Table("DocumentComputedRights"); 

      Id(x => x.Id, map => 
      { 
       map.Generator(IdGeneratorSelector.CreateGenerator()); 
      }); 

//more not important properties... 

      ManyToOne(x => x.OrganisationalUnit, map => 
      { 
       map.Column("OrganisationalUnit"); 
       map.NotNullable(false); 
       map.Cascade(Cascade.None); 
      }); 

     } 
    } 

public class OrganisationUnitMapping : ClassMapping<NHOrganisationalUnit> 
    { 
     public OrganisationUnitMapping() 
     { 
      Table("OrganisationalUnits"); 
      Id(x => x.Id, map => 
           { 
            map.Generator(IdGeneratorSelector.CreateGenerator()); 
           }); 

//more not important properties... 

     } 
    } 

Благодарность

+0

Работает ли он с 'cp.OrganisationalUnit == person'? – Firo

+0

нет т.к. проблема в .Select (U => cp) часть. Когда я удаляю это (или меняю на Select (u => cp.Id), то этот запрос работает. – robocik

+0

Есть ли ссылка на NHDocumentComputedRight на NHFolder? – Firo

ответ

0

Я думаю, что у вас есть проблемы с оператором выбора, вы пытались что-то вроде этого:

var right = _session.QueryOver<NHFolder>() 
    .JoinAlias(b => b.DocumentComputedRights,() => cp) 
    .Select(x => x.DocumentComputedRights) 
    .Where(h => h.Id == rightsHolder.Id && cp.OrganisationalUnit.Id == person.Id) 
    .List<NHDocumentComputedRight>(); 

Это то, что работает для меня, поэтому оно должно работать и в вашем случае.

Я бы предположил, что основной причиной проблемы является отсутствие надлежащей перегрузки по методу Select. На самом деле вы хотели бы написать это следующим образом:

.JoinAlias(b => b.DocumentComputedRights,() => cp) 
.Select(() => cp) 

но Expression<Func<object>> не существует. Надеюсь, он будет включен в следующую версию.

+0

Я попробовал запрос, но я получаю это исключение: [SELECT this_.Id as y0_ FROM Folders this_ internal join DocumentComputedRightsFolder documentco3_ on this_.Id = documentco3_.nhfolder_key внутреннее соединение DocumentComputedRights cp1_ on documentco3_.elt = cp1_.Id WHERE (this_.Id = @ p0 и cp1_.OrganisationalUnit = @ p1)] Имя: cp0 - Значение: 65536 Имя: cp1 - Значение: 32769. Но странно, что этот запрос (в sql) возвращает NHFolder id (this_.Id), а не NHDocumentComputedRights – robocik

+0

и для ваша информация это отношение ManyToMany между NHFolder и NHDocumentComputedRights – robocik

+0

Можете ли вы вставить свои сопоставления? ed sql не кажется правильным - какую версию NHibernate вы используете? – MonkeyCoder

2

Критерии AFAIK/queryOver могут возвращать только объект, который был создан для (NHFolder в вашем примере), или столбцы, которые установлены в сущность с aliastobean. вы можете сделать коррелированный подзапрос.

var subquery = QueryOver.Of<NHFolder>() 
    .JoinAlias(b => b.DocumentComputedRights,() => cp) 
    .Where(h => h.Id == rightsHolder.Id && cp.OrganisationalUnit.Id == person.Id) 
    .Select(u => cp.Id); 

var right = _session.QueryOver<NHDocumentComputedRight>() 
    .WithSubquery.Where(r => r.Id).Eq(subquery) 
    .SingleOrDefault<NHDocumentComputedRight>();