2010-06-11 88 views
2

我有一個SecurityGroup實體女巫有Memebers和應用程序屬性。 應用程序是查找。NHibernate標準轉換結果

所以securityGroups在許多一對多與用戶表和

關係一個一對多與LookupApplciation(FK),現在我要選擇鏈接到一個特定用戶的所有應用程序。

我有如下標準:

public IList<LookupApplication> GetApplicationByUser(User user) 
    { 
     return 
      this.Session.CreateCriteria(typeof(SecurityGroup), "sg") 
      .CreateAlias("Members", "u") 
      .CreateAlias("Application", "al") 
      .Add(Restrictions.Eq("u.Id", user.Id)) 

      .List<LookupApplication>(); 

    } 

它trows異常

The value "Edi.Advance.Core.Model.Security.SecurityGroup" is not of type "Edi.Advance.Core.Model.Lookups.LookupApplication" and cannot be used in this generic collection. 
Parameter name: value 

,這是正確的。

我如何可以改變結果IList<LookupApplication>?

感謝

回答

3

只能返回類型,你從中創建標準。

從你必須將代碼開始最簡單的方法:

return 
     this.Session.CreateCriteria(typeof(SecurityGroup), "sg") 
     .CreateAlias("Members", "u") 
     .CreateAlias("Application", "al") 
     .Add(Restrictions.Eq("u.Id", user.Id)) 
     .List<SecurityGroup>() 

     // get the lookup applications in memory 
     .SelectMany(x => x.LookupApplications); 

此加載所有SecurityGroups到內存中,即使只需要LookupApplication秒。當你無論如何需要它們或者它們很小時,這可能不是問題。

你也可以反向查詢,並從LookupApplication

return 
     this.Session.CreateCriteria(typeof(LookupApplication), "la") 
     // requires navigation path from SecurityGroup to LookupApplication 
     .CreateCriteria("la.SecurityGroup", "sg") 
     .CreateAlias("Members", "u") 
     .CreateAlias("Application", "al") 
     .Add(Restrictions.Eq("u.Id", user.Id)) 
     .List<LookupApplication>() 

啓動或使用HQL,其中有一些條件不具備的特性,items會從一個集合中的所有項目:

select sg.LookupApplications.items 
from SecurityGroup sg inner join sg.Members u 
where u.Id = :userId 

當您沒有動態查詢時,實際推薦使用HQL。

更新,從isuruceanu的評論:

Session 
    .CreateQuery(
     @"select sg.Application 
     from SecurityGroup sg 
      inner join sg.Members u 
     where u.Id = :userId") 
    .SetParameter("userId", user.Id) 
    .List<LookupApplication>(); 
+0

第一個作品的罰款。其次,不像LookupApplication是一個查找實體,它不知道securityGroups。 第三個是hql :) 所以第一個對我來說是最好的一個,因爲只生成一個select語句。謝謝 – isuruceanu 2010-06-11 13:14:21

+0

爲什麼推薦HQL?我通常不喜歡hql,雖然用於寫4年的TSQL:D – isuruceanu 2010-06-11 13:19:04

+0

Session。的createQuery( 「從SecurityGroup SG內選擇sg.Application加入sg.MembersÙ其中u.Id =:用戶id」) .SetParameter( 「用戶id」,user.Id)的.List (); 最終查詢:) 謝謝,我應該回顧一下關於hqls的觀點 – isuruceanu 2010-06-11 13:25:49

0

這取決於SecurityGroup的樣子和LookupApplication的樣子。

您可以使用使用ResultTransformer像:

.SetResultTransformer(Transformers.AliasToBean<LookupApplication>()) 
.List<LookupApplication>(); 

誠然,SecurityGroup具有性能matchinig LookupAppliaction,否則你就不得不設計像那些屬性:

.SetProjection(NHibernate.Criterion.Projections.ProjectionList()  
.Add(Projections.Property("Number"), "OrderNumber") 
.Add(Projections.Property("CreatedOn"), "CreatedOn") 
    .Add(Projections.Property("MemeberName"), "Name")) 
.SetResultTransformer(Transformers.AliasToBean<LookupApplication>()) 
.List<LookupApplication>();