4

我有以下父实体部门,其中包含一组子实体部分

public class Department  
{
    private Iesi.Collections.Generic.ISet<Section> _sections;
    public Department()
    {
        _sections = new HashedSet<Section>();
    }
    public virtual Guid Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual ICollection<Section> Sections
    {
        get { return _sections; }
    }
    public virtual int Version { get; set; }
}

public partial class Section  
{
    public Section()
    {
        _employees = new HashedSet<Employee>();
    }
    public virtual Guid Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual Department Department { get;  protected set; }
    public virtual int Version { get; set; }
}

我想将其转换(展平)为以下 DTO

public class SectionViewModel
{
    public string DepartmentName { get; set; }
    public string  SectionName { get; set; }
}

使用以下代码。

SectionModel sectionModel = null;
Section sections = null;
var result = _session.QueryOver<Department>().Where(d => d.Company.Id == companyId)
            .Left.JoinQueryOver(x => x.Sections, () => sections)
            .Select(
                    Projections.ProjectionList()
                        .Add(Projections.Property<Department>(d => sections.Department.Name).WithAlias(() => sectionModel.DepartmentName))
                        .Add(Projections.Property<Department>(s => sections.Name).WithAlias(() => sectionModel.SectionName))
                   )
            .TransformUsing(Transformers.AliasToBean<SectionModel>())
            .List<SectionModel>();

但是,我收到以下异常:无法解析属性:Department.Name of: Domain.Section

我什至尝试过以下 LINQ 表达式

        var result = (from d in _session.Query<Department>()
                      join s in _session.Query<Section>()
                          on d.Id equals s.Department.Id into ds
                      from sm in ds.DefaultIfEmpty()
                      select new SectionModel
                          {
                              DepartmentName = d.Name,
                              SectionName = sm.Name ?? null
                          }).ToList();

映射

public class DepartmentMap : ClassMapping<Department>
{
    public DepartmentMap()
    {           
        Id(x => x.Id, m => m.Generator(Generators.GuidComb));
        Property(x => x.Name,
            m =>
            {
                m.Length(100);
                m.NotNullable(true);
            });

        Set(x => x.Sections,
                    m =>
                    {
                        m.Access(Accessor.Field);
                        m.Inverse(true);
                        m.BatchSize(20);
                        m.Key(k => { k.Column("DeptId"); k.NotNullable(true); });
                        m.Table("Section");
                        m.Cascade( Cascade.All | Cascade.DeleteOrphans);
                    },
                    ce => ce.OneToMany());
    }
}


public class SectionMap : ClassMapping<Section>
{
    public SectionMap()
    {
        Id(x => x.Id, m => m.Generator(Generators.GuidComb));
        Property(x => x.Name,
            m =>
            {
                m.Length(100);
                m.NotNullable(true);
            });
        ManyToOne(x => x.Department,
                m =>
                {
                    m.Column("DeptId");
                    m.NotNullable(true);
                });
    }
}

但这会抛出一个方法或操作没有执行

寻求有关我做错了什么或遗漏的指导。

4

3 回答 3

2

NHibernate 不知道如何通过父实体访问子属性的子项。关于 QueryOver 的一个有用的事情是它被直接翻译成 SQL。您无法编写以下 SQL:

select [Section].[Department].[Name]

正确的?因此,您不能在 QueryOver 中做同样的事情。我将为Department您开始的实体创建一个别名,并在您的投影列表中使用它:

Department department;
Section sections;    

var result = _session.QueryOver<Department>(() => department)
    .Where(d => d.Company.Id == companyId)
    .Left.JoinQueryOver(x => x.Sections, () => sections)
    .Select(
            Projections.ProjectionList()
                .Add(Projections.Property(() => department.Name).WithAlias(() => sectionModel.DepartmentName))
                .Add(Projections.Property(() => sections.Name).WithAlias(() => sectionModel.SectionName))
           )
    .TransformUsing(Transformers.AliasToBean<SectionModel>())
    .List<SectionModel>();

我在您的评论中注意到您想要一个order by条款。如果您需要帮助,请告诉我,我可能会想出。

希望有帮助!

于 2013-06-21T12:12:58.910 回答
0

您是否尝试过类似的 linq 查询

from d in Departments
from s in d.Sections
select new SectionModel
{
DepartmentName = d.Name,
SectionName = s == null ? String.Empty : s.Name
}
于 2013-06-19T21:13:20.797 回答
0

这现在可以在3.3.3中修复。寻找

  • 新功能
  • [NH-2986] - 添加将集合包含到投影中的功能

不确定,但如果这是你的问题,但如果你没有使用 3.3.3,那么升级并检查一下。

还可以查看JIRA

于 2013-06-18T12:56:21.047 回答