通过NHibernate制作IQueryable更喜欢Join over Exists

时间:2014-06-17 17:55:17

标签: c# sql linq fluent-nhibernate automapping

如果我写下面的代码:

session.Query<Parent>.Count( p => p.Children.Any( c => c.Name == "Child" && c.Age == 10 ) );

生成的SQL是:

select cast(count(*) as INT) as col_0_0_ from "Parent" parent0_ 
where exists (select children1_.Id from "Child" children1_ where parent0_.Id=children1_.Parent_id and children1_.Name=? and children1_.Age=?)

由于SQL CE 4.0中的性能观察,我更喜欢连接,例如:

select cast(count(*) as INT) as col_0_0_ from "Parent" parent0_
join "Child" children1_ on parent0_.Id = children1_.Parent_id 
where children1_.Name=? and children1_.Age=?

我确定我在NHibernate上表现不佳,但经过多次尝试后,我仍然无法弄清楚如何在没有恢复到QueryOver或HQL的情况下加入表格,但我确实比如拥有IQueryable<T>定义的依赖关系。有人会暗示我朝着正确的方向前进吗?

2 个答案:

答案 0 :(得分:1)

我想查询孩子,然后引用父母会得到你想要的东西。

session.Query<Child>()
       .Where( c => c.Name == "Child")
       .Where( c => c.Age == 10)
       .Select( c=> c.Parent)
       .Count();

答案 1 :(得分:1)

您的第二个查询与第一个查询不同:它计算孩子的数量,而不是父母。

如果您想要一个计算父项的连接,您必须使查询返回每个父项一个子项。我不知道正确的LINQ to NHibernate语法,但在简单的LINQ中它看起来像

(from p in Parents
 from c in p.Children.Where(c => c.Name == "Child" && c.Age == 10)
            .Take(1)
 select p).Count()

如果没有导航属性(尽管最好使用它):

(from p in Parents
 from c in Children.Where(c => c.Name == "Child" && c.Age == 10
                            && c.ParentId == p.Id)
                   .Take(1)
 select p).Count()