NHibernate выполняет посторонние операторы выбора - PullRequest
4 голосов
/ 26 октября 2009

Задача

При выполнении get для сущности с отношением многие-к-одному, для внешнего соединения установлено значение true, для not-found установлено значение игнорирования, а строка сущности на одной стороне не существует, NHibernate выполняет дополнительный выбор пытаясь загрузить его, хотя предыдущий выбор, который был только что выполнен, не может его найти.

Вопрос

Почему выполняется этот дополнительный выбор и есть ли способ его подавления?

Контекст

Я работаю с устаревшей базой данных без ограничений внешнего ключа, где у меня нулевой контроль над схемой. Изменение этого, к сожалению, не может быть и речи. Имейте в виду, что мои фактические отображения более сложны, чем это. Это происходит несколько раз для реальной сущности, и они часто загружаются ICriteria.List<T>(), а не Session.Load<T>(id), что приводит к большому количеству ненужных запросов и значительному снижению производительности.

Упрощенный пример


Код
ISession Session = ...
...
Session.Get<Bid>(1);
...
Выполненный SQL
SELECT bid.Id, bid.ItemId, item.Id FROM Bid bid left outer join Item item on bid.ItemId=item.Id WHERE bid.Id=@p0;@p0 = 1
SELECT item.Id FROM Item item WHERE item.Id=@p0;@p0 = 222
картографирование
<?xml version="1.0" encoding="utf-8" ?>  
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Example" namespace="Example">  
   <class name="Bid">  
     <id name="Id">  
       <generator class="native"/>  
     </id>  
     <many-to-one name="Item" column="ItemId" outer-join="true" not-found="ignore" />  
   </class>  
   <class name="Item">  
     <id name="Id">  
       <generator class="native"/>  
     </id>  
   </class>  
 </hibernate-mapping>  
Содержание таблицы ставок
Id  ItemId    
1   222  
Элемент Таблица Содержание
Id  
333  
444  

Ответы [ 2 ]

1 голос
/ 28 октября 2009

ОК, похоже, что это определенно ошибка в NHibernate, как вы можете видеть здесь . На данный момент он помечен как второстепенный, поэтому я думаю, что голосование за него может поднять его профиль и привести в порядок.

0 голосов
/ 28 октября 2009

Без настройки я бы предположил, что ключом является замена external-join = "true" на fetch = "join" в ассоциации "многие к одному". По умолчанию режим выборки связи «многие-к-одному» - «выбор», и я подозреваю, что это вызывает выполнение выбора.

Если вы измените это отображение на:

 <many-to-one name="Item" column="ItemId" fetch="join" not-found="ignore" />  

он должен вести себя так, как вы ожидаете.

...