Ho il seguente dominio impostato per la persistenza con NHibernate: Uso NHibernate Criteria API per selezionare insieme specifico di dati insieme con un conteggio
Sto usando la PaperConfiguration come aggregato radice.
Desidero selezionare tutti gli oggetti PaperConfiguration per un determinato Tier e AcademicYearConfiguration. Funziona molto bene come nell'esempio seguente:
ICriteria criteria =
session.CreateCriteria<PaperConfiguration>()
.Add(Restrictions.Eq("AcademicYearConfiguration", configuration))
.CreateCriteria("Paper")
.CreateCriteria("Unit")
.CreateCriteria("Tier")
.Add(Restrictions.Eq("Id", tier.Id))
return criteria.List<PaperConfiguration>();
(Forse c'è un modo migliore di farlo però).
Tuttavia, è anche necessario sapere quanti ReferenceMaterials ci sono per ogni PaperConfiguration e vorrei ottenerlo nella stessa chiamata. Evitare HQL - Ho già una soluzione HQL per questo.
So che questo è ciò che le proiezioni sono per e this question suggerisce un'idea ma non riesco a farlo funzionare.
Ho un PaperConfigurationView che ha, invece di IList<ReferenceMaterial> ReferenceMaterials
del ReferenceMaterialCount e stava pensando lungo le linee di
ICriteria criteria =
session.CreateCriteria<PaperConfiguration>()
.Add(Restrictions.Eq("AcademicYearConfiguration", configuration))
.CreateCriteria("Paper")
.CreateCriteria("Unit")
.CreateCriteria("Tier")
.Add(Restrictions.Eq("Id", tier.Id))
.SetProjection(
Projections.ProjectionList()
.Add(Projections.Property("IsSelected"), "IsSelected")
.Add(Projections.Property("Paper"), "Paper")
// and so on for all relevant properties
.Add(Projections.Count("ReferenceMaterials"), "ReferenceMaterialCount")
.SetResultTransformer(Transformers.AliasToBean<PaperConfigurationView>());
return criteria.List<PaperConfigurationView>();
purtroppo questo non funziona. Che cosa sto facendo di sbagliato?
La seguente query semplificata:
ICriteria criteria =
session.CreateCriteria<PaperConfiguration>()
.CreateCriteria("ReferenceMaterials")
.SetProjection(
Projections.ProjectionList()
.Add(Projections.Property("Id"), "Id")
.Add(Projections.Count("ReferenceMaterials"), "ReferenceMaterialCount")
).SetResultTransformer(Transformers.AliasToBean<PaperConfigurationView>());
return criteria.List<PaperConfigurationView>();
crea questo SQL piuttosto inaspettata:
SELECT
this_.Id as y0_,
count(this_.Id) as y1_
FROM Domain.PaperConfiguration this_
inner join Domain.ReferenceMaterial referencem1_
on this_.Id=referencem1_.PaperConfigurationId
La query sopra non riesce con l'errore ADO.NET in quanto, ovviamente, non è una corretta SQL dal momento che manca un gruppo di o il conteggio è il conteggio (referencem1_.Id) piuttosto che (this_.Id).
mappature NHibernate:
<class name="PaperConfiguration" table="PaperConfiguration">
<id name="Id" type="Int32">
<column name="Id" sql-type="int" not-null="true" unique="true" index="PK_PaperConfiguration"/>
<generator class="native" />
</id>
<!-- IPersistent -->
<version name="VersionLock" />
<!-- IAuditable -->
<property name="WhenCreated" type="DateTime" />
<property name="CreatedBy" type="String" length="50" />
<property name="WhenChanged" type="DateTime" />
<property name="ChangedBy" type="String" length="50" />
<property name="IsEmeEnabled" type="boolean" not-null="true" />
<property name="IsSelected" type="boolean" not-null="true" />
<many-to-one name="Paper" column="PaperId" class="Paper" not-null="true" access="field.camelcase"/>
<many-to-one name="AcademicYearConfiguration" column="AcademicYearConfigurationId" class="AcademicYearConfiguration" not-null="true" access="field.camelcase"/>
<bag name="ReferenceMaterials" generic="true" cascade="delete" lazy="true" inverse="true">
<key column="PaperConfigurationId" not-null="true" />
<one-to-many class="ReferenceMaterial" />
</bag>
</class>
<class name="ReferenceMaterial" table="ReferenceMaterial">
<id name="Id" type="Int32">
<column name="Id" sql-type="int" not-null="true" unique="true" index="PK_ReferenceMaterial"/>
<generator class="native" />
</id>
<!-- IPersistent -->
<version name="VersionLock" />
<!-- IAuditable -->
<property name="WhenCreated" type="DateTime" />
<property name="CreatedBy" type="String" length="50" />
<property name="WhenChanged" type="DateTime" />
<property name="ChangedBy" type="String" length="50" />
<property name="Name" type="String" not-null="true" />
<property name="ContentFile" type="String" not-null="false" />
<property name="Position" type="int" not-null="false" />
<property name="CommentaryName" type="String" not-null="false" />
<property name="CommentarySubjectTask" type="String" not-null="false" />
<property name="CommentaryPointScore" type="String" not-null="false" />
<property name="CommentaryContentFile" type="String" not-null="false" />
<many-to-one name="PaperConfiguration" column="PaperConfigurationId" class="PaperConfiguration" not-null="true"/>
</class>
Perché la seconda query di criteri non funziona? Qualche messaggio di errore? (Suppongo che manchi una clausola group by, ma voglio essere sicuro di ciò che hai incontrato.) –
Puoi per favore pubblicare i tuoi mapping? –
Domani includerò i mapping per essere sicuro di averli catturati adeguatamente. Per quanto riguarda il messaggio di errore - è possibile vedere dalla query SQL che non sarebbe corretto - ma a questo punto sembra irrilevante dal momento che mi aspetto che un conteggio provenga da una query secondaria ma non ci sono nemmeno JOIN o query secondarie. – mfloryan