非hibernate条件投影导致查询效率低下



请看下面的例子,这是我的代码的一个非常简化的版本:

Dim Criteria = Session.CreateCriteria(Of Person)()
Criteria.SetProjection(Projections.Property("Car"))
return Criteria.List(Of Car)()

这工作完美,然而NHibernate 3.1创建两个查询来获取结果。比如:

SELECT CarId FROM Person WHERE blababla

,然后每一行:

SELECT color, brand, wheels FROM Car WHERE CarId = ?

这不是很有效,所以我尝试:

Criteria.CreateAlias("Car", "Car")
Criteria.SetFetchMode("Car", NHibernate.FetchMode.Join)

什么都不做。我怎么能强迫NHibernate在第一个查询上做一个连接,这样我就可以往返MySql服务器了?

当您执行Projections.Property("Car")并且Car是多对一引用时,它只是成为Projections.Property("Car.Id")的别名。如果你想获得实际的Car对象,你有两个选项:

选项1:在投影列表中指定汽车的所有属性。

Criteria.CreateAlias("Car", "Car")
Criteria.SetFetchMode("Car", NHibernate.FetchMode.Join)
Criteria.SetProjection(Projections.Projectionist() _
           .Add(Projections.Property("Car.Color")) _
           .Add(Projections.Property("Car.Brand")))

如果wheels是另一个实体列表,那么它会变得更加棘手。

选项2:从Car的角度指定查询

Criteria.CreateCriteria(Of Car)()
Criteria.CreateAlias("Person", "person")
... //specify your criteria

还有一个额外的选项,不使用投影,并获得Person对象与获取的Car对象

我找到了一个使用子查询的解决方案。这将工作,但我认为这仍然会更有效地使用连接,所以我原来的问题仍然存在。我的解决方案:

var cars = s.CreateCriteria<Cars>()
    .Add(Subqueries.PropertyIn("Id",
        DetachedCriteria.For<Person>()
            .Add(Restrictions.Eq("Name","MyName"))
            .SetProjection(Projections.Property("Car.Id"))
        ))
    .List<Cars>();

最新更新