NHibernate:将子实体投影到父属性会引发异常

我有以下父实体部门,其中包含子实体部分的集合

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

但是抛出一个方法或操作没有实现.

寻求关于我做错了什么或错过的指导.

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

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

对?因此,您无法在QueryOver中执行相同的操作.我会为你开始的部门实体创建一个别名,并在投影列表中使用它:

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子句.如果您需要帮助,请告诉我,我可能会想出来.

希望有所帮助!

点赞