我认为这个问题是由忽略FetchKind属性引起的。
我有一张员工表:
Employee
{
ID
Name
PositionCode
}
和一个位置表:
Position
{
Code
Description
}
我使用Mapping连接了这些表。ByCode并将Fetch设置为Join,但它似乎不起作用。
我看过十几篇问同样问题的帖子,但似乎都没有得到明确的答案。
public class EmployeeMapper: ClassMapping<Employee>
{
public EmployeeMapper()
{
Lazy(false);
Table("EMPLOYEE");
Id(x => x.Id, m => m.Column("ID");
MapToOne(c => c.PositionCode, posMap =>
{
posMap.Lazy(LazyRelation.NoLazy);
posMap.Fetch(FetchKind.Join)
posMap.Column("CODE");
}
}
}
我使用了NHibernate探查器,它的行为如下:
Select all employees
foreach employee
select position
请注意,这不是一个sql select语句,如果有1000名员工,它将扩展到1001个select语句(一个用于所有员工,然后每个职位一个)。
如果有人能帮忙,我们将不胜感激。
避免1+N问题的一般NHibernate方法是使用BatchSize()
设置。这种方式应该比在映射中使用JOIN Fetching更合适(让我们用它来查询)
其中有两个:
- 实体级别
- 集合级别
请参阅Adam Bar的"按代码映射-实体级映射",在这里我们可以看到按代码支持的映射:
BatchSize(25)
通常,NHibernate会使用In子句一次加载更多的集合(Lists、Maps),其中包含更多的parentId。这将导致cca 1+(N/25)。。。我认为这是合理的。
直到我们不再需要收集。。。它懒洋洋地装着。如果我们需要,它的所有零件都是分批装载的。
还有一些类似的链接,与BatchSize
设置和1+N问题有关:
- NHibernate QueryOver,Fetch生成多个sql查询和数据库命中
- 这是在NHibernate中急切加载子集合的正确方式吗
- https://stackoverflow.com/questions/18419988/