je le domaine suivant mis en place pour la persistance avec NHibernate: utilisant NHibernate API critères pour sélectionner ensemble spécifique de données ainsi qu'un nombre
J'utilise le PaperConfiguration comme agrégat racine.
Je souhaite sélectionner tous les objets PaperConfiguration pour un niveau donné et AcademicYearConfiguration. Cela fonctionne très bien selon l'exemple suivant:
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>();
(Il existe peut-être une meilleure façon de procéder).
Encore besoin de savoir combien de ReferenceMaterials il y a pour chaque PaperConfiguration et je voudrais l'obtenir dans le même appel. Évitez HQL - J'ai déjà une solution HQL pour cela.
Je sais que c'est ce que les projections sont pour et this question suggère une idée, mais je ne peux pas le faire fonctionner.
J'ai un PaperConfigurationView qui a, au lieu de la IList<ReferenceMaterial> ReferenceMaterials
ReferenceMaterialCount et a été pensée le long des lignes de
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>();
Malheureusement, cela ne fonctionne pas. Qu'est-ce que je fais mal?
La requête simplifiée suivante:
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>();
crée ce SQL plutôt inattendu:
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 requête ci-dessus échoue avec l'erreur de ADO.NET car il est évidemment pas un SQL correct car il manque un groupe par ou le compte étant count (referencem1_.Id) plutôt que (this_.Id).
applications 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>
Pourquoi la deuxième requête de critères ne fonctionne-t-elle pas? Des messages d'erreur? (Je suppose qu'il manque une clause group by, mais je veux être sûr de ce que vous avez rencontré.) –
Pouvez-vous s'il vous plaît poster vos correspondances? –
Je vais inclure les cartographies demain pour m'assurer que je les ai capturées de manière adéquate. En ce qui concerne le message d'erreur - vous pouvez voir à partir de la requête SQL, il ne serait pas correct - mais à ce stade, cela ne semble pas pertinent car je suppose qu'un compte proviendrait d'une sous-requête mais pas de sous-requête. – mfloryan