1

请参阅以下示例,这是我的代码的一个非常简化的版本:

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 服务器?

4

2 回答 2

0

当你这样做Projections.Property("Car")并且 Car 是一个多对一的引用时,它只是成为Projections.Property("Car.Id"). 如果您想获得实际的 Car 对象,您有 2 个选项:

选项 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")))

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

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

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

还有一个附加选项,不使用投影并使用获取的 Car 对象获取 Person 对象

于 2011-04-28T16:32:28.560 回答
0

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

var cars = s.CreateCriteria<Cars>()
    .Add(Subqueries.PropertyIn("Id",
        DetachedCriteria.For<Person>()
            .Add(Restrictions.Eq("Name","MyName"))
            .SetProjection(Projections.Property("Car.Id"))
        ))
    .List<Cars>();
于 2011-04-28T21:03:42.597 回答