NHibernate:将子实体投影到父属性会引发异常
我有以下父实体部门,其中包含子实体部分的集合NHibernate:将子实体投影到父属性会引发异常,nhibernate,queryover,nhibernate-projections,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
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; }
}
使用以下代码
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>();
SectionModel SectionModel=null;
节=空;
var result=\u session.QueryOver()。其中(d=>d.Company.Id==companyId)
.Left.JoinQueryOver(x=>x.节,()=>Sections)
.选择(
投影。投影列表()
.Add(Projections.Property(d=>sections.Department.Name).WithAlias(()=>sectionModel.DepartmentName))
.Add(Projections.Property(s=>sections.Name).WithAlias(()=>sectionModel.SectionName))
)
.TransformUsing(Transformers.AliasToBean())
.List();
但是,我遇到以下异常:无法解析属性:部门。名称:域。节
我甚至尝试过以下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();
var result=(来自_session.Query()中的d)
在_session.Query()中加入s
d.Id等于s.Department.Id到ds
来自ds.DefaultIfEmpty()中的sm
选择新截面模型
{
部门名称=d.名称,
SectionName=sm.Name??空
}).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);
});
}
}
公共类部门映射:类映射
{
公共部门地图()
{
Id(x=>x.Id,m=>m.Generator(Generators.GuidComb));
属性(x=>x.Name,
m=>
{
m、 长度(100);
m、 不可为空(true);
});
设置(x=>x.截面,
m=>
{
m、 访问(Accessor.Field);
m、 逆(真);
m、 批量大小(20);
m、 键(k=>{k.Column(“DeptId”);k.NotNullable(true);});
m、 表(“章节”);
m、 级联(Cascade.All | Cascade.deleteOlivers);
},
ce=>ce.OneToMany());
}
}
公共类分区映射:类映射
{
公共分区图()
{
Id(x=>x.Id,m=>m.Generator(Generators.GuidComb));
属性(x=>x.Name,
m=>
{
m、 长度(100);
m、 不可为空(true);
});
多通(x=>x.部门,
m=>
{
m、 列(“DeptId”);
m、 不可为空(true);
});
}
}
但这会抛出一个方法或操作未实现
寻求关于我做错了什么或遗漏了什么的指导。这一问题现在可以在中解决。寻找
- 新功能
- [NH-2986]-添加将集合包含到投影中的功能
还可以查看您是否尝试过像这样的linq查询
from d in Departments
from s in d.Sections
select new SectionModel
{
DepartmentName = d.Name,
SectionName = s == null ? String.Empty : s.Name
}
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>();
部门;
章节;
var result=\u session.QueryOver(()=>部门)
.其中(d=>d.Company.Id==companyId)
.Left.JoinQueryOver(x=>x.节,()=>Sections)
.选择(
投影。投影列表()
.Add(Projections.Property(()=>department.Name).with别名(()=>sectionModel.DepartmentName))
.Add(Projections.Property(()=>sections.Name).with别名(()=>sectionModel.SectionName))
)
.TransformUsing(Transformers.AliasToBean())
.List();
我注意到在你的评论中,你想要一个orderby
子句。如果你需要帮助,请告诉我,我可能会想出办法
希望有帮助 已升级到3.3.3,但问题仍然存在。问题可能在于查询的结构。此抛出的指定方法不受支持。异常。您正在运行的特定linq查询是什么?您的映射看起来像什么?我使用NH3.0及以上版本运行过类似的查询,没有问题。对不起!我的错误。我从部门中的d调用了错误的
方法。可以工作,但返回一个内部联接,而我对左联接感兴趣,因为有些部门没有分区。您需要从分区到部门显式联接。。。或者只需选择部门名称即可。你知道SQL是什么样子吗?下面是预期的SQL选择d.Name作为deptName,选择s.Name作为SectionName,从d.id=s.deptid按d.Name asc排序,选择s.Name asc
这有效。我明白我错在哪里了。是的,我想要一份
订单,但我能处理。谢谢你的耐心和麻烦。@CallMeKags:没问题!我知道有时候很难弄清楚什么是问号。
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>();