Ich habe folgende Domain für die Persistenz mit NHibernate eingerichtet: Mit NHibernate Criteria API bestimmtem Satz von Daten auszuwählen, zusammen mit einer Zählung
ich die PaperConfiguration als Root-Aggregat verwenden.
Ich möchte alle PaperConfiguration-Objekte für eine bestimmte Tier-und AcademicYearConfiguration auswählen. Dies funktioniert wirklich gut wie im folgenden Beispiel:
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>();
(Vielleicht gibt es eine bessere Möglichkeit, dies zu tun, obwohl).
Aber auch müssen Sie wissen, wie viele ReferenceMaterials gibt es für jede PaperConfiguration und ich möchte es im selben Anruf erhalten. Vermeiden Sie HQL - ich habe bereits eine HQL-Lösung dafür.
Ich weiß, das ist, was Projektionen sind und this question schlägt eine Idee vor, aber ich kann es nicht zum Laufen bringen.
Ich habe einen PaperConfigurationView, dass anstelle von IList<ReferenceMaterial> ReferenceMaterials
die ReferenceMaterialCount hat und wurde nach dem Vorbild der
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>();
denken leider nicht funktioniert. Was mache ich falsch?
Die folgende vereinfachte Abfrage:
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>();
schafft diese eher unerwartete SQL:
SELECT
this_.Id as y0_,
count(this_.Id) as y1_
FROM Domain.PaperConfiguration this_
inner join Domain.ReferenceMaterial referencem1_
on this_.Id=referencem1_.PaperConfigurationId
Die obige Abfrage mit ADO.NET Fehler fehlschlägt, da es offensichtlich keine korrekte SQL ist, da es fehlt eine Gruppe durch oder der Zählwert wird gezählt (referencem1_.Id) anstatt (this_.Id).
NHibernate Zuordnungen:
<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>
Warum funktioniert die zweite Kriterienabfrage nicht? Irgendwelche Fehlermeldungen? (Ich nehme an, es fehlt eine Gruppenklausel, aber Sie wollen sicher sein, was Sie angetroffen haben.) –
Können Sie bitte Ihre Mappings posten? –
Ich werde die Mappings morgen aufnehmen, um sicherzustellen, dass ich sie angemessen erfasst habe. In Bezug auf die Fehlermeldung - Sie können sehen, aus der SQL-Abfrage wäre es nicht korrekt - aber an dieser Stelle scheint es irrelevant, da ich eine Anzahl von einer Unterabfrage erwarten würde, aber es gibt sogar keine JOIN oder Unterabfrage dort. – mfloryan