nHibernate QueryOver and JoinQueryOver



我对nHibernate相当陌生,我一直在尝试编写查询。我似乎做不好。我的模型中有一个"产品",其中包含"组件"的ICollection。我需要找到包含组件引用以字母"G"开头的任何组件的所有产品。我试过这个:

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

但是,我收到一个编译错误,说"委托系统.Func>>不接受 1 个参数。

JoinQueryOver上有一个重载,我可以在其中传递表达式>>

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

我已经尝试了各种其他方法使用.演员和加入别名,但它们似乎只是不必要的复杂。

谁能指出我哪里出错了?

提前致谢

在这种情况下

,我建议使用子查询。它可能看起来像这样

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

最新更新