c# download - NHibernate e raccolta conta





docs install (3)


È possibile creare una classe DTO che si utilizza per la segnalazione / panoramiche, per esempio ... Questa classe potrebbe avere il seguente aspetto:

public class PersonView
{
     public string Name{ get;set; }
     public int NumberOfSubordinates{get;set;}     
}

Quindi, si crea una query di criteri, in quel criterio si definisce che si desidera recuperare tutte le persone. Tuttavia, è possibile specificare che NHibernate non deve restituire oggetti Person, ma oggetti PersonView. Per poter fare ciò, dovrai utilizzare una proiezione e un AliasToBeanTransformer:

ICriteria crit = new Criteria(typeof(Person));

crit.SetProjection (Projections.ProjectionList()
                       .Add (Projections.Property("Name"), "Name")
                       .Add (Projections.Count ("Subordinates"), "NumberOfSubordinates");

crit.SetResultTransformer(Transformers.AliasToBean (typeof(PersonView));

Qualcosa come sopra. (Non ho testato la tua situazione specifica). Quindi, devi solo far sapere a NHibernate dell'esistenza della classe PersonView, semplicemente "importando" questa classe. Ho un file hbm.xml, in cui importa tutte le mie classi DTO. Questo sembra

<hibernate-mapping .. >
  <import class="PersonView" />
</hibernate-mapping>

Quindi, NHibernate genererà una query per i tuoi Criteri che assomiglia molto a:

SELECT p.Name, COUNT(p.Subordinates) FROM Person
INNER JOIN Subordinates ON Person.PersonId = Subordinates.PersonID
GROUP BY p.Name

Ho la seguente configurazione di classe per la persistenza usando NHibernate

public class Person
{
    public string Name { get; set; }
    public IList<Person> Subordinates { get; set; }
}

Ora dì che ho una griglia con due colonne, "Nome" e "Numero di subordinati" qual è il modo migliore per farlo in NHibernate, pur mantenendo l'uso di oggetti di dominio laddove possibile.

Grazie




Supponendo che tu abbia l'HBM corretto che Persona ha molti Subordinati puoi solo ottenere una persona e poi chiamare Subordinates.Count

Si tratta di un processo moderatamente dispendioso se tutto ciò di cui hai bisogno è il conteggio poiché popolerà completamente tutta la raccolta Subordinates per ottenere solo il conteggio. Penso che faresti meglio a creare un metodo che raccolga una Persona e ti restituisca un conteggio dei loro Subordinati e usi HQL per eseguire una funzione di conteggio reale. Se non è possibile eseguire una funzione di conteggio diretto, è possibile fare in modo che restituisca solo un singolo valore per subordinato corrispondente a FK Persona e quindi chiama. Lunghezza o .Count sulla raccolta restituita. Tuttavia, presumo che HQL possa essere in grado di contarlo direttamente per te.




Mentre i nomi simili, l'utilizzo è diverso.

I. Projections.distinct(Projections.property("id"));

questa dichiarazione sarebbe stata tradotta in SQL Statement. Verrà passato a DB Engine ed eseguito come SQL DISTINCT . Vedere:

quindi ad esempio questo esempio:

List results = session.createCriteria(Cat.class)
    .setProjection( Projections.projectionList()
        .add( Projections.distinct(Projections.property("id")) )
    )
    .list();

sembrerebbe:

SELECT DISTINCT(cat_id) FROM cat_table

II. criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

Questa affermazione è eseguita ex-post . Una volta che la query SQL dal motore DB viene restituita e Hibernate esegue l'iterazione del set di risultati per convertirlo nell'elenco delle nostre entità.

Ma è necessario sempre? NO, per lo più questo non è necessario.

L'unico caso, quando DEVE usarlo, se c'è un'associazione nella query - UNIRE la fine one-to-many .

Perché se abbiamo un cat e i suoi due kittens , questo restituirebbe due righe, mentre il cat è solo uno:

SELECT cat.*, kitten.*
FROM cat_table as cat 
  INNER JOIN kitten_table kitten ON kitten.cat_id = cat.cat_id

Quindi, la dichiarazione alla fine dei criteriaQuery :

... // criteriaQuery joining root and some one-to-many
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

risulterebbe in una lista con un solo gatto.





c# nhibernate