Возврат объекта через проекционный запрос - PullRequest
3 голосов
/ 27 января 2010

Можно ли вернуть объект, используя проекционный запрос?

Я успешно сделал это с помощью SQL-запроса (см. Ниже), но не могу найти способ сделать это с помощью проекционного запроса.

Dim sql As String = "SELECT {a.*}, {b.*} FROM a LEFT OUTER JOIN b ON a.pk = b.fk")

' Convert SQL results into entities {a} and {b}
Dim query As IQuery = session.CreateSQLQuery(sql) _
                                  .AddEntity("a", GetType(a)) _
                                  .AddEntity("b", GetType(b))

Return query.List()

1 Ответ

6 голосов
/ 27 января 2010

Да, вы можете возвращать объекты из проекционных запросов.

Если вы используете HQL-запрос, вы можете указать конструктор для данного класса в предложении HQL select:

IList<Foo> foos = session.CreateQuery(
    "select new Foo(f.Name, f.Value) from Foo f")
    .List<Foo>();

В этом примере требуется, чтобы класс Foo имел конструктор, который соответствует сигнатуре, используемой в HQL-запросе. То есть:

Вы также можете использовать AliasToBean ResultTransformer, который автоматически сопоставляет значения, возвращаемые запросом, со свойствами заданного типа. Этот подход требует, чтобы псевдонимы, используемые в запросе, отображались непосредственно на свойства данного типа. Например:

IList<Foo> foos = session.CreateQuery(
    "select f.Name as Name, f.Value as Value from Foo f")
    .SetResultTransformer(Transformers.AliasToBean<Foo>())
    .List<Foo>();

Чтобы эти примеры работали, класс Foo может выглядеть следующим образом:

public class Foo
{
    public Foo() { }

    public Foo(string name, double value)
    {
        Name = name;
        Value = value;
    }

    public virtual string Name { get; set; }
    public virtual double Value { get; set; }
}

Приведенный выше класс содержит допустимый конструктор для первого примера HQL. Он также определяет открытые свойства, которые соответствуют псевдонимам, используемым во втором запросе HQL, что позволяет преобразователю AliasToBean заполнять сущности типа Foo из результатов запроса.

Однако из приведенного вами примера кажется, что вы хотите вернуть два типа сущностей из одного и того же проекционного запроса. Это может быть труднее достичь с помощью этих методов. Я сделал пару быстрых тестов, без всякой удачи.

Обновление:

Вы можете использовать преобразователь результатов AliasToBean как с Criteria API, так и с HQL. Преобразователь используется таким же образом, но проекционный запрос выглядит несколько иначе с использованием критериев. Вот пример, который использует запрос критерия:

IList<Foo> foos = session.CreateCriteria<Foo>()
    .SetProjection(Projections.ProjectionList()
        .Add(Projections.Property("Name"), "Name")
        .Add(Projections.Property("Value"), "Value"))
    .SetResultTransformer(Transformers.AliasToBean<Foo>())
    .List<Foo>();
...