nHibernate QueryOver和JoinQueryOver

时间:2014-02-08 16:38:21

标签: nhibernate join ienumerable queryover icollection

我是nHibernate的新手,我一直在尝试编写查询。我似乎无法做对。我的模型中有一个“Product”,其中包含ICollection“Component”。我需要找到所有包含任何组件引用以字母“G”开头的组件的产品。我试过这个:

var matching = session.QueryOver<Product>()
   .JoinQueryOver<Component>(p => p.Components)
   .Where(c => c.ComponentReference.StartsWith("G")).List();

但是我收到一个编译错误,说'委托System.Func&gt;&gt;不带1个参数。

JoinQueryOver上有一个重载,我可以传入Expression&gt;&gt;

所以我认为我的查询会起作用,因为ICollection实现了IEnumerable。

我尝试过使用.Cast和JoinAlias的其他各种方法,但它们看起来似乎并不复杂。

有谁可以指出我哪里出错?

提前致谢

1 个答案:

答案 0 :(得分:0)

在这种情况下,我建议使用子查询。它可能看起来像这样

Product product = null;
Component component = null;

// the subselect, returning the Product.ID
// only if the Component.ComponentReference is like G%
var subQuery = QueryOver.Of<Component>(() => component)
    .WhereRestrictionOn(() => component.ComponentReference)
        .IsLike("G", MatchMode.Start)
    .Select(c => c.Product.ID);

// the root Product
var query = session.QueryOver<Product>(() => product)
    .WithSubquery
    .WhereProperty(() => product.ID) 
    .In(subQuery);

// and finally the list
var list = query
    .List<Product>();

生成的SQL将是这样的:

SELECT product
FROM product
WHERE productId IN (SELECT ProductId FROM Component WHERE ComponenentReferece LIKE 'G%')

为什么要使用子查询而不是JOIN?因为在这种情况下,连接会产生Carthesian产品。返回的产品集将乘以以G%

开头的所有组件

子查询将产生纯粹,扁平的产品集,因此我们可以正确使用分页(.Take() .Skip()