2009-09-28 2 views
5

Ich habe folgende Domain für die Persistenz mit NHibernate eingerichtet: DomainMit 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> 
+0

Warum funktioniert die zweite Kriterienabfrage nicht? Irgendwelche Fehlermeldungen? (Ich nehme an, es fehlt eine Gruppenklausel, aber Sie wollen sicher sein, was Sie angetroffen haben.) –

+0

Können Sie bitte Ihre Mappings posten? –

+0

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

Antwort

1

Sie sollten Projections.GroupProperty() verwenden, statt Projections.Property().

+0

Danke. Ich habe tatsächlich mit diesem Ansatz experimentiert, indem ich Property und GroupProperty ausprobiert habe, aber keine Ergebnisse erzielt habe. – mfloryan

Verwandte Themen