Question

Is it possible to return an entity using a projection query?

I've successfully done it with a SQL query (see below), but can't find how to do it with a projection query.

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()
Was it helpful?

Solution

Yes, you can return entities from projection queries.

If you are using a HQL query you can specify a constructor for the given class in the HQL select clause:

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

This example requires that the Foo class has a constructor that fits the signature used in the HQL query. I.e:

You could also use the AliasToBean ResultTransformer, which automatically maps the values returned from the query to the properties of a given type. This approach requires that the aliases used in the query map directly to properties of the given type. For example:

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

To make these examples work, the Foo class could look like this:

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; }
}

The class above contains a valid constructor for the first HQL example. It also defines public properties that align with the aliases used in the second HQL query, which makes it possible for the AliasToBean transformer to fill entities of the type Foo from the results of the query.

However, from the example that you give, it seems as if you want to return two types of entities from the same projection query. That might be harder to achieve using these methods. I did a couple of quick tests, without any luck.

Update:

You can use the AliasToBean result transformer with the Criteria API as well as with HQL. The transformer is used in the same way, but the projection query looks a bit different using Criteria. Here is an example that uses a criteria query:

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>();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top