Domanda

public class SearchText
{
    public virtual int Id { get; set; }
    public virtual string Text { get; set; }
}

public class SearchTextLog
{
    public virtual int Id { get; set; }
    public virtual SearchText SearchText { get; set; }
    public virtual User User { get; set; }
    public virtual int SearchCount { get; set; }
    public virtual DateTime LastSearchDate { get; set; }
}
.

Sto cercando di selezionare i 5 migliori elementi di searchtext in base alla somma del loro conteggio all'interno del searchtextlog. Attualmente sono stato in grado di risolvere questo problema eseguendo prima una query per ottenere i primi 5 elementi, quindi utilizzare il risultato all'interno di una seconda query. Mi stavo chiedendo se qualcuno potesse mostrarmi la luce e insegnarmi come potrei integrare queste due domande separate in una singola unità.

Ecco cosa ho attualmente:

var topSearchCriteria = Session.CreateCriteria(typeof (SearchTextLog))
            .SetProjection(Projections.ProjectionList()
                            .Add(Projections.GroupProperty("SearchText.Id"))
                            .Add(Projections.Alias(Projections.Sum("SearchCount"), "SearchCount")))
            .AddOrder(Order.Desc("SearchCount"))
            .SetMaxResults(topSearchLimit)
            .List<int>();

return Session.CreateCriteria<SearchText>()
            .Add(Restrictions.In("Id", topSearchCriteria.ToArray()))
            .List<SearchText>();
.

Modifica:

Oh no, ho appena realizzato che la mia soluzione attuale perderà l'ordine importante da parte dei risultati. Quindi dovrò assolutamente incorporare le domande. : - /

Modifica:

Ho provato anche una mappatura bidirezionale per consentire la seguente dichiarazione, tuttavia, non riesco a restituire gli articoli di searchtext. Si lamenta semplicemente che le proprietà di searttext non sono in un raggruppamento.

return Session.CreateCriteria<SearchText>()
                .CreateAlias("SearchTextLogs", "stl")
                .AddOrder(Order.Desc(Projections.Sum("stl.SearchCount")))
                .SetMaxResults(topSearchLimit)        
                .SetResultTransformer(Transformers.AliasToEntityMap)
                .List<SearchText>();
.

Scusa la mia ignoranza, ma Nibernate è completamente nuova per me e richiede un modo di pensare completamente diverso.

È stato utile?

Soluzione

OK, penso di aver capito una soluzione.

La mia soluzione originale secondo la mia domanda non funzionerà perché Nibernate non supporta ancora la possibilità di eseguire un gruppo per proprietà senza aggiungerlo alla clausola di selezione (vedere: Testo del collegamento ).

Mentre si precipita tuttavia, mi sono imbattuto in queste cose interessanti chiamate ResultTransformers. L'utilizzo del trasformatore di risultato AliastoBean Nibernate mapperà automaticamente gli alias che do a ciascun elemento di proiezione alle proprietà con lo stesso nome all'interno di un tipo specificato. Ho semplicemente specificato il mio oggetto SearchText (tuttavia, ho dovuto aggiungere una proprietà TOTALSearchount aggiuntiva per l'elemento di proiezione della somma). Ha popolato i miei oggetti perfettamente e li restituirono.

return Session.CreateCriteria(typeof(SearchTextLog))
            .CreateAlias("SearchText", "st")
            .SetProjection(Projections.ProjectionList()
                                .Add(Projections.Alias(Projections.GroupProperty("st.Id"), "Id"))
                                .Add(Projections.Alias(Projections.GroupProperty("st.Text"), "Text"))
                                .Add(Projections.Alias(Projections.Sum("SearchCount"), "TotalSearchCount")))
            .SetMaxResults(topSearchLimit)
            .AddOrder(Order.Desc("TotalSearchCount"))
            .SetResultTransformer(Transformers.AliasToBean(typeof(SearchText)))
            .List<SearchText>();
.

Sono sorpreso che questo non fosse più facile da fare. Mi ha portato da 4 a 5 ore di ricerca e dev a capire questo. Speriamo che la mia esperienza NHibernate diventerà più facile con sempre più esperienza.

Spero che questo aiuti a qualcun altro là fuori!

Altri suggerimenti

Non funziona?

var critterRes = Session.CreateCriteria(typeof (SearchTextLog))
            .SetProjection(Projections.ProjectionList()
                            .Add(Projections.GroupProperty("SearchText"))
                            .Add(Projections.Property("SearchText"))
                            .Add(Projections.Alias(Projections.Sum("SearchCount"), "SearchCount")))
            .AddOrder(Order.Desc("SearchCount"))
            .SetMaxResults(topSearchLimit)
            .List<SearchText>()
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top