NHibernate和JoinAlias抛出异常

时间:2012-01-25 09:24:20

标签: nhibernate queryover

我在HQL中查询哪个效果很好:

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中实现此查询?

更新(添加映射) - 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...

        }
    }

由于

2 个答案:

答案 0 :(得分:2)

AFAIK criteria / queryOver只能返回为其创建的实体(在您的示例中为NHFolder)或者使用aliastobean设置为entity的列。你可以做一个相关的子查询。

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>();

答案 1 :(得分:0)

我认为你的select语句有问题,你尝试过这样的事情:

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>>不存在。希望它将包含在下一个版本中。