NHibernate: Projecting child objects into parent properties throws an exception

I have the following parent object that contains a collection of child objects. Sections

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

I would like to convert (smooth) it to the next DTO

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

Using the following code.

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

However, I get the following exception: Failed to resolve property: Department.Name of: Domain.Section

I even tried the following LINQ expression

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

Mappings

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

But this calls the method or the operation is not implemented .

Looking for guidance on what I'm doing wrong or missing.

+4
source share
3 answers

NHibernate does not know how to access the child of the child through the parent. A useful thing to keep in mind about QueryOver is that it translates directly to SQL. You cannot write the following SQL:

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

right? Therefore, you cannot do the same in QueryOver. I would create an alias for the Department object you start with and use it in my prediction list:

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

In your comment, I noticed that you need an order by clause. Let me know if you need help with this, and I might come up with this.

Hope this helps!

+2
source

Now this can be fixed in 3.3.3 . Find

  • New feature
  • [NH-2986] - Add the ability to include collections in forecasts

Not sure, but if this is your problem, but if you are not using 3.3.3, update it and check.

Take a look at Jira

0
source

Have you tried linq query like

 from d in Departments from s in d.Sections select new SectionModel { DepartmentName = d.Name, SectionName = s == null ? String.Empty : s.Name } 
0
source

Source: https://habr.com/ru/post/1486710/


All Articles