请参阅以下示例,该示例是我的代码的简化版本:
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服务器进行一次往返?
答案 0 :(得分:0)
执行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")))
如果轮子是另一个实体列表,那么它会变得更加棘手。
选项2: 从汽车的角度指定查询
Criteria.CreateCriteria(Of Car)()
Criteria.CreateAlias("Person", "person")
... //specify your criteria
还有一个额外的选项,即不使用投影并使用获取的Car对象获取Person对象
答案 1 :(得分: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>();