Domanda

E 'possibile restituire un entità che utilizza una query di proiezione?

L'ho fatto con successo con una query SQL (vedi sotto), ma non riesce a trovare il modo di farlo con una query di proiezione.

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()
È stato utile?

Soluzione

Sì, è possibile restituire le entità dalle query di proiezione.

Se si utilizza una query HQL è possibile specificare un costruttore per la classe di cui l'HQL selezionare clausola:

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

In questo esempio è necessario che la classe Foo ha un costruttore che si inserisce la firma utilizzato nella query HQL. Cioè:

È anche possibile utilizzare l'AliasToBean ResultTransformer, che mappa automaticamente i valori restituiti dalla query per le proprietà di un determinato tipo. Questo approccio richiede che gli alias utilizzati nella mappa query direttamente alle proprietà di un dato tipo. Ad esempio:

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

Per rendere questi esempi funzionano, la classe Foo potrebbe assomigliare a questo:

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

La classe di cui sopra contiene un costruttore valida per il primo esempio HQL. Definisce anche proprietà comuni che si allineano con gli alias utilizzati nella seconda query HQL, che rende possibile per il trasformatore AliasToBean per riempire le entità del tipo Foo dai risultati della query.

Tuttavia, l'esempio che si dà, sembra come se si vuole restituire due tipi di entità dalla stessa query di proiezione. Che potrebbe essere più difficile da raggiungere con questi metodi. Ho fatto un paio di test rapidi, senza alcuna fortuna.

Aggiornamento:

È possibile utilizzare il trasformatore risultato AliasToBean con l'API Criteri così come con HQL. Il trasformatore è utilizzato nello stesso modo, ma la query proiezione sembra un po 'diverso utilizzando criteri. Ecco un esempio che utilizza una query criteri:

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>();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top