mam następujące domeny skonfigurowane do utrzymywania się z NHibernate: Korzystanie NHibernate Criteria API, aby wybrać określony zestaw danych wraz z liczbą
Używam PaperConfiguration jako kruszywo korzeniowego.
Chcę wybrać wszystkie obiekty PaperConfiguration dla danego poziomu i AcademicYearConfiguration. Działa to bardzo dobrze, jak w poniższym przykładzie:
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>();
(Być może jest lepszy sposób to zrobić).
Należy również wiedzieć, ile materiałów referencyjnych jest dostępnych dla każdej konfiguracji PaperConfiguration i chciałbym uzyskać je w tym samym wywołaniu. Unikaj HQL - już mam do tego rozwiązanie HQL.
Wiem, do czego służą prognozy, a this question sugeruje pomysł, ale nie mogę go uruchomić.
Mam PaperConfigurationView który ma zamiast IList<ReferenceMaterial> ReferenceMaterials
ReferenceMaterialCount i myślał wzdłuż linii
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>();
niestety to nie działa. Co ja robię źle?
Następująca kwerenda uproszczony:
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>();
tworzy to raczej nieoczekiwane 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
Powyższa kwerenda nie powiedzie się z powodu błędu ADO.NET, gdyż oczywiście nie jest poprawny SQL, ponieważ brakuje liczona jest grupa lub liczba (referencem1_.Id), a nie (this_.Id).
NHibernate mapowania:
<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>
Dlaczego drugie zapytanie o kryteria nie działa? Jakieś komunikaty o błędach? (Zakładam, że brakuje w nim klauzuli group by, ale chcę mieć pewność, co napotkasz.) –
Czy możesz opublikować swoje mapowania? –
Będę uwzględniał jutro mapowania, aby upewnić się, że je odpowiednio przechwyciłem. Odnośnie komunikatu o błędzie - widać z zapytania SQL, że nie jest ono poprawne - ale w tym momencie wydaje się nieistotne, ponieważ oczekiwałbym, że licznik pochodzi z sub zapytania, ale nie ma tam nawet JOIN ani sub zapytania. – mfloryan