2013-06-24 78 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. –