nhibernate критерии проекции приводит к неэффективным запросам - PullRequest
1 голос
/ 28 апреля 2011

Пожалуйста, посмотрите следующий пример, который является очень упрощенной версией моего кода:

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?

Ответы [ 2 ]

0 голосов
/ 29 апреля 2011

Я нашел обходной путь, используя подзапрос. Это будет работать, но я думаю, что это было бы более эффективно при использовании объединения, поэтому мой первоначальный вопрос остается в силе. Мой обходной путь:

var cars = s.CreateCriteria<Cars>()
    .Add(Subqueries.PropertyIn("Id",
        DetachedCriteria.For<Person>()
            .Add(Restrictions.Eq("Name","MyName"))
            .SetProjection(Projections.Property("Car.Id"))
        ))
    .List<Cars>();
0 голосов
/ 28 апреля 2011

Когда вы делаете 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: Укажите запрос с точки зрения автомобиля

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

Существует также дополнительная опция не использования проекций и получения объекта Person с выбранным объектом Car.

...