Еще одна правка:
Думаю, я наконец узнал, что происходит. Похоже, что поставщик LINQ to NHibernate испытывает проблемы при перемещении ассоциаций от цели к исходной таблице и генерирует отдельное объединение каждый раз, когда он сталкивается с такой ассоциацией.
Поскольку вы не предоставляете свое сопоставление, я использовал сопоставление из linq-to-nhibernate-продукции-ненужный-объединения . Эта модель имеет Документ с одним заданием и многими TranslationUnits . Каждый TranslationUnit имеет множество Перевод сущностей.
Когда вы пытаетесь найти Перевод, основанный на задании, вы пересекаете ассоциации в обратном порядке, и поставщик LINQ генерирует несколько объединений: одно для Translation -> TranslationUnit и одно для TranslationUnit to Document.
Этот запрос будет генерировать избыточные объединения:
session.Query<TmTranslation>()
.Where(x => x.TranslationUnit.Document.Job == job)
.OrderBy(x => x.Id)
.ToList();
Если вы измените порядок навигации на Document -> TranslationUnit -> Translation, вы получите запрос, который не создает никаких избыточных объединений:
var items=(from doc in session.Query<Document>()
from tu in doc.TranslationUnits
from translation in tu.Translations
where doc.Job ==job
orderby translation.Id
select translation).ToList();
Учитывая эту причудливость, QueryOver кажется лучшим вариантом.
Предыдущее редактирование:
Я подозреваю, что виновником является compset.A.B.CurrentSeason . Первая объединенная таблица (fwbcompeti1_) возвращает A .B, в то время как следующие две (fwbcompeti2_ и fwbseason3_) используются для возврата A. B . Поставщик LINQ to NHibernate, похоже, не догадывается, что A нигде больше не используется и не может удалить его из сгенерированного оператора.
Попробуйте немного помочь оптимизатору, заменив CurrentSeason = compset.ABCurrentSeason на CurrentSeason = true из select , поскольку ваш оператор where возвращает только элементы с CurrentSeason == true.
РЕДАКТИРОВАТЬ: Я имею в виду, чтобы изменить запрос следующим образом:
List<Competitions> dtoCompetitions;
dtoCompetitions = (from compset in session.Query<FWBCompetitionSet>()
where compset.HeadLine == true
&& compset.A.B.CurrentSeason == true
select (new Competitions
{
CompetitionSetID = compset.CompetitionSetID,
Name = compset.Name,
Description = compset.Description,
Area = compset.Area,
Type = compset.Type,
CurrentSeason = true,
StartDate = compset.StartDate
}
)).ToList();
Я просто заменяю значение compset.A.B.CurrentSeason на true