2013-06-24 77 views
1

我已經很好地瞭解了這個問題的答案,並且有幾個問題表明這是無法完成的。NHibernate的子集合投影到DTO

Nhibernate projection with child collection

NHibernate QueryOver projections - projecting collections to DTO

NHibernate Projections - how to project collections

所以我想知道什麼是圍繞一個良好的工作項目的子集到我的DTO。 我需要運行兩個獨立的投影並手動將孩子添加到父級?

我使用NH 3.3.1我有以下DTO數據結構

public class ProviderDto 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public IList<EmployerDTO> Employers { get; set; } 
} 


public class EmployerDTO 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

} 

我想我的供應商和僱主域實體映射到該結構的投影。 (在這種簡單的情況下,我的域名實體與我的域名系統非常相似)

Employer employerAlias = null; 
Provider providerAlias = null; 
ProviderDto providerDto = null; 

var dto = session.QueryOver<Provider>(() => providerAlias) 
      .JoinAlias(x => x.Employers,() => employerAlias) 
      .Where(()=> providerAlias.Id == 1) 
      .Select(Projections.ProjectionList() 
      .Add(Projections.Property(() => providerAlias.Id).WithAlias(() => providerDto.Id)) 
      .Add(Projections.Property(() => providerAlias.Name).WithAlias(() => providerDto.Name)) 

       //This is where I cannot project my child employer collection 
      .TransformUsing(Transformers.AliasToBean<ProviderDto>()).List<ProviderDto>(); 

我該如何映射整個子集合? 非常感謝。

回答

2

您應該使用期貨批量查詢並自行構建關係。

Employer employerAlias = null; 
Provider providerAlias = null; 
ProviderDto providerDto = null; 
EmployerDto employerDto = null; 

var providers = session.QueryOver<Provider>(() => providerAlias) 
     .JoinAlias(x => x.Employers,() => employerAlias) 
     .Where(()=> providerAlias.Id == 1) 
     .Select(Projections.ProjectionList() 
     .Add(Projections.Property(() => providerAlias.Id).WithAlias(() => providerDto.Id)) 
     .Add(Projections.Property(() => providerAlias.Name).WithAlias(() => providerDto.Name)) 
     .TransformUsing(Transformers.AliasToBean<ProviderDto>()).Future<ProviderDto>(); 

var employers = session.QueryOver<Employer>(() => employerAlias) 
//Etc 
.TransformUsing(Transformers.AliasToBean<EmployerDto>()).Future<EmployerDto>(); 

然後,這是一個正確的僱主映射到供應商的問題。您可能需要在DTO中提供更多信息,但使用Future查詢時,您只能進行一次數據庫往返以獲取所有信息。

編輯:

爲了得到哪些僱主映射到哪些提供者。

session.QueryOver(() => provider) 
     .JoinAlias(() => provider.Employers,() => employer) 
     .SelectList(list => list.Select(() => provider.Id).WithAlias(() =>  peDTO.ProviderId) 
           .Select(() => employer.Id).WithAlias(() =>  peDTO.EmployerId)) 
     .TransformUsing(Transformers.AliasToBean<ProviderEmployerMapDTO>()).Future<ProviderEmployerMapDTO>(); 
+0

很好。只要試試這個。回來一分鐘。 – jonho

+0

我可以問一下。在第二個(僱主)預測中,處理「where」條款的最佳方法是什麼?顯然我需要檢索所有與我剛剛批處理的供應商相關的僱主。但提供者與僱主之間只有單向關係。謝謝 – jonho

+0

這就是爲什麼我說DTO可能需要修改。你可以把ProviderId放在僱主面前嗎?或者它是多對多的?如果它是多對多的,你可以寫一個ProviderId列表的投影:EmployerId作爲第三個將來的查詢(添加另一個叫做ProviderEmployerDTO的DTO)。請記住,您希望對所有查詢使用相同的限制。即:ProviderId == 1. –