I have 2 objects, ExamType
which has a list of Exams
.
I want with nhibernate to fetch an ExamType with its list of exams.
If I run this query:
session.QueryOver<Examtype>(() => examTypeAlias)
.JoinAlias(e => e.Exams, () => examAlias)
.Where(e => e.Id == 12345)
.Future<Examtype>();
the generated SQL is
SELECT
examType.Id as id,
exam1.Id as examId,
exam1.ExamTypeId as examExamTypeId,
FROM
Examtype examType
inner join Exam exam1 on examType.Id = exam1.ExamTypeId
WHERE
examType.Id = 12345
and the problem is that the retrieved ExamType object will do a lazy load of exams.
Then if I run the query:
session.QueryOver<Examtype>(() => examTypeAlias)
.Left.JoinAlias(e => e.Exams, () => examAlias)
.Where(e => e.Id == 12345)
.Future<Examtype>();
the generated SQL is
SELECT
examType.Id as id,
exam1.Id as examId1,
exam1.ExamTypeId as examExamTypeId1,
exam2.Id as examId2,
exam2.ExamTypeId as examExamTypeId2,
FROM
Examtype examType
left outer join Exam exam1 on examType.Id = exam1.ExamTypeId
WHERE
examType.Id = 12345
and this time, there is an eager loading of exams.
I don't understand why the second query generated twice the same columns of Exam and why in the first query where the join is inner, exams are not fetched as the SQL query result fetches all records.
Any idea?
I can't say why but that's default behavior - only left join collections are fetched in Criteria/QueryOver queries.
Though in NHibernate 5.2+ you can enable fetching with additional Fetch(SelectMode.Fetch, () => examAlias)
call:
session.QueryOver<Examtype>(() => examTypeAlias)
.JoinAlias(e => e.Exams, () => examAlias)
.Fetch(SelectMode.Fetch, () => examAlias) //<-- Fetch provided aliases
.Where(e => e.Id == 12345)
.Future<Examtype>();
See https://github.com/nhibernate/nhibernate-core/pull/1599 for all SelectMode
options explained.