tengo el siguiente dominio establecido para la persistencia con NHibernate: los criterios del API para seleccionar conjunto específico de datos junto con un recuento
estoy usando el PaperConfiguration como la suma de la raíz.
Quiero seleccionar todos los objetos PaperConfiguration para un Nivel determinado y AcademicYearConfiguration. Esto funciona muy bien como en el siguiente ejemplo:
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>();
(aunque hay una forma mejor de hacerlo).
Pero también necesito saber cuántos ReferenceMaterials hay para cada PaperConfiguration y me gustaría obtenerlo en la misma llamada. Evite HQL: ya tengo una solución HQL para ello.
Sé que esto es para lo que son las proyecciones y this question sugiere una idea, pero no puedo hacer que funcione.
Tengo un PaperConfigurationView que tiene, en lugar de la IList<ReferenceMaterial> ReferenceMaterials
ReferenceMaterialCount y estaba pensando en la línea 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>();
lamentablemente esto no funciona. ¿Qué estoy haciendo mal?
La siguiente consulta simplificada:
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 este SQL bastante inesperado:
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 consulta anterior falla con el error ADO.NET, ya que, obviamente, no es un SQL correcta, ya que no se encuentra un grupo por o el recuento que es recuento (referencem1_.Id) en lugar de (this_.Id).
asignaciones de 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>
¿Por qué la segunda consulta de criterios no funciona? Cualquier mensaje de error? (Supongo que falta una cláusula group by, pero quiero asegurarme de lo que encontraste). –
¿Puedes publicar tus mapeos? –
Incluiré las asignaciones mañana para asegurarme de haberlas capturado adecuadamente. En cuanto al mensaje de error (puede ver que no es correcto en la consulta SQL), en este punto parece irrelevante, ya que esperaría que un recuento fuera de una consulta secundaria, pero ni siquiera hay ENTRADA ni sub consulta. – mfloryan