我是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的其他各种方法,但它们看起来似乎并不复杂。
有谁可以指出我哪里出错?
提前致谢
答案 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()
)