Linq для NHibernate, генерирующий несколько соединений с одной таблицей

#sql #linq #nhibernate #join

#sql #linq #nhibernate #Присоединиться

Вопрос:

Когда у меня есть ссылка на ту же таблицу в моем select, что и в моем предложении where, linq для Nhibernate генерирует два соединения, одно для select и одно для where . т. е.

 from child in Session.Query<Child>()
where child.Parent.Name == "Bob" 
select new Info 
{ 
   ParentAge = child.Parent.Age, 
   ChildName = child.Name
};
  

Генерирует SQL, подобный:

 Select this_.Name,
       parent1.Age
From Child this_
     left join Parent parent1 on child.ParentId = parent1.Id,
Parent parent2

Where child.ParentId = parent2.Id and parent2.Name = 'Bob'
  

Я бы подумал, что мне следует использовать SQL, более похожий:

 Select this_.Name,
       parent1.Age
From Child this_
         inner join Parent parent1 on child.ParentId = parent1.Id
Where parent1.Name = 'Bob'
  

Есть ли способ структурировать запрос, чтобы получить это?
Имеет ли это значение?

Комментарии:

1. как вы настроили файл сопоставления? Вы установили для параметра cascade значение false ?

Ответ №1:

Вы можете запретить NHibernate делать это, используя прозрачный идентификатор, чтобы ваш запрос выглядел следующим образом:

 from child in Session.Query<Child>()
let p = child.Parent
where p.Name == "Bob" 
select new Info { 
    ParentAge = p.Age, 
    ChildName = child.Name
};
  

Ответ №2:

Вы пробовали сравнивать план выполнения запроса для каждого из них в SSMS? Если дублированное соединение устранено в SQL Server, то это не имеет значения. Я обнаружил, что это имеет место в нескольких случаях, когда я думал, что сгенерированный запрос будет очень неэффективным, но после оптимизации он заканчивается точно так же, как запрос, который выглядит намного лучше.

Комментарии:

1. Спасибо, Джоэл, В этом случае, конечно, оптимизатор SQL Server эффективно генерирует один и тот же план выполнения для каждого запроса, так что на самом деле это не имеет значения. Для более сложных случаев мне, возможно, придется просто попробовать и посмотреть.