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

标签 nhibernate queryover nhibernate-projections

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

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 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条款。如果您需要帮助,请告诉我,我可能会想出它。

希望有帮助!

关于NHibernate:将子实体投影到父属性中会引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17156917/

相关文章:

unit-testing - 如何在不设置 NHibernate session 的情况下测试软删除事件监听器

c# - NHibernate 中的 QueryOver 子项可为空

Nhibernate 投影与子集合

NHibernate 投影、AutoMapping、IPagedList,怎么做?

c# - 批量HQL插入

.NET、SQL Server、NHibernate 和高精度小数

.net - Spring.Net(和NHibernate?),缺少异常翻译器

nhibernate - 如何在 Nhibernate QueryOver 中获取具有子项计数的父实体列表

IUserType 上的 NHibernate QueryOver

sql - 如何使用 NHibernate 构建字符串查询?