2011-09-09 5 views
5

Sto usando questa query:evitare inutili croce si unisce nella query conteggio di codice SQL generato

return from oi in NHibernateSession.Current.Query<BlaInteraction>() 
select new BlaViewModel 
{ 
    ... 

    NoPublications = oi.Publications.Count(), 

    ... 
}; 

BlaInteraction contiene un IList di pubblicazioni (vale a dire le entità). Per determinare il numero di pubblicazioni non è davvero necessario fare tutti i join per una pubblicazione. Posso impedire che nhibernate utilizzi i join nello sql generato (ad esempio utilizzando la proiezione ???) in qualche modo?

Grazie.

Christian

PS:

Questo è ciò produce NH (leggermente adattato):

select cast(count(*) as INT) from RelationshipStatementPublications publicatio21_, Publication publicatio22_ inner join Statements publicatio22_1_ on publicatio22_.StatementId=publicatio22_1_.DBId where publicatio21_.StatementId = 22762181 and publicatio21_.PublicationId=publicatio22_.StatementId 

Questo è quello che sarebbe sufficiente:

select cast(count(*) as INT) from RelationshipStatementPublications publicatio21_ where publicatio21_.StatementId = 22762181 
+0

Sai che * è * idratare le pubblicazioni? Che cosa dice SQL Profiler in realtà viene eseguito sul server? – AakashM

+0

Grazie - mi dispiace, hai ragione. I join non hanno nulla a che fare con 'idratazione'. Ho modificato la domanda e aggiunto alcuni sql. – cs0815

+0

(non un esperto osceno) il fatto che genera un implciti 'CROSS JOIN' (le tabelle nella clausola' FROM' che non sono esplicitamente unite) suggerisce che NHibernate non ha una certa conoscenza delle relazioni tra gli oggetti; tuttavia, vorrei prima controllare i piani di esecuzione SQL della sua query e la query ideale - potrebbe essere che * SQL Server * sia in grado di calcolare la cosa più semplice. – AakashM

risposta

2

Ok la soluzione migliore che ho trovato finora è quello di utilizzare una formula FNH:

mapping.Map(x => x.NOPublications).Formula("(select count(distinct RelationshipStatementPublications.PublicationId) from RelationshipStatementPublications where RelationshipStatementPublications.StatementId = DBId)"); 

public virtual int NOPublications {get; private set;} 

quando ho mappa dal dominio al modello di vista che uso:

NoPublications = oi.NOPublications, 

Christian

3

Perché non è possibile hai appena creato un'altra query?

Session.QueryOver<Publication>().Where(x => x.BlaInteractionId == idSentAsParameter).Select(Projections.RowCount()).SingleOrDefault<int>(); 

Penso che sia funzionerà

return from oi in NHibernateSession.Current.Query<BlaInteraction>() 
select new BlaViewModel 
{ 
    ... 
    NoPublications = Session.QueryOver<Publication>().Where(x => x.BlaInteractionId == oi.Id).Select(Projections.RowCount()).SingleOrDefault<int>(); 

    ... 
}; 

Un'altra modifica, hai provato lazy="extra"?

+0

Grazie. Puoi per favore elaborare questo? Ho una classe BlaInteraction che contiene un IList . La mia query associa alcune proprietà di BlaInteraction al modello di visualizzazione e conta il numero di pubblicazioni di ogni BlaInteraction (TOP n). Il motivo del mio appraoch è che voglio sfruttare appieno il "motore di espressione basato su Linq" di telerik che genera tutte le "cose" per il filtraggio, il paging e l'ordinamento. – cs0815

+0

Aggiunto un altro esempio, verificare se è ok –

+0

Questo non funziona e ho provato questo prima che lo hai postato. Le cose sono che BlaInteraction è derivato dall'affermazione. qualsiasi affermazione ha Ilist che viene mappato utilizzando mapping.HasManyToMany (x => x.Publications) .Tabella ("RelationshipStatementPublications"); e ho anche un'entità RelationshipStatementPublications dedicata. quindi qualcosa del genere dovrebbe funzionare: NoPublications = NHibernateSession.Current.QueryOver (). Where (x => x.Statement.Id == oi.Id) .Select (Projections.RowCount()). SingleOrDefault () , ma ottengo un'eccezione di percorso. – cs0815

Problemi correlati