2009-09-28 30 views
5

Tôi có lĩnh vực sau đây được thiết lập để kiên trì với NHibernate: DomainSử dụng NHibernate Tiêu chuẩn API để chọn bộ dữ liệu cụ thể cùng với một số

Tôi đang sử dụng PaperConfiguration như là tổng hợp root.

Tôi muốn chọn tất cả các đối tượng PaperConfiguration cho một Tier và AcademicYearConfiguration đã cho. Điều này hoạt động thực sự tốt theo ví dụ sau:

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>(); 

(Có lẽ cách tốt hơn để làm điều này).

Tuy nhiên, cũng cần phải biết có bao nhiêu tài liệu tham chiếu có cho mỗi PaperConfiguration và tôi muốn nhận được nó trong cùng một cuộc gọi. Tránh HQL - Tôi đã có một giải pháp HQL cho nó.

Tôi biết đây là dự đoán cho và this question gợi ý ý tưởng nhưng tôi không thể làm cho nó hoạt động.

Tôi có một PaperConfigurationView có, thay vì IList<ReferenceMaterial> ReferenceMaterials các ReferenceMaterialCount và đã suy nghĩ dọc theo dòng của

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>(); 

không may này không hoạt động. Tôi đang làm gì sai?

Truy vấn đơn giản sau đây:

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>(); 

tạo SQL khá bất ngờ này:

SELECT 
    this_.Id as y0_, 
    count(this_.Id) as y1_ 
FROM Domain.PaperConfiguration this_ 
    inner join Domain.ReferenceMaterial referencem1_ 
    on this_.Id=referencem1_.PaperConfigurationId 

Các truy vấn trên không thành công với lỗi ADO.NET vì nó rõ ràng không phải là một SQL đúng vì nó là mất tích một nhóm hoặc số đếm được tính (referencem1_.Id) thay vì (this_.Id).

ánh xạ 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> 
+0

Tại sao truy vấn tiêu chí thứ hai không hoạt động? Bất kỳ thông báo lỗi nào? (Tôi cho rằng nó thiếu một nhóm theo điều khoản, nhưng muốn chắc chắn những gì bạn gặp phải.) –

+0

Bạn có thể vui lòng đăng ánh xạ của mình không? –

+0

Tôi sẽ bao gồm các bản đồ vào ngày mai để đảm bảo rằng tôi đã chụp chúng đầy đủ. Về thông báo lỗi - bạn có thể thấy từ truy vấn SQL nó sẽ không đúng - nhưng tại thời điểm này có vẻ như không liên quan vì tôi mong đợi một số từ truy vấn phụ nhưng thậm chí không có JOIN hoặc truy vấn phụ ở đó. – mfloryan

Trả lời

1

Bạn nên sử dụng Projections.GroupProperty() thay vì Projections.Property().

+0

Cảm ơn bạn. Tôi đã thực sự thử nghiệm với phương pháp này thử cả Property và GroupProperty nhưng không mang lại kết quả. – mfloryan

Các vấn đề liên quan