Domanda

Problema

Quando si esegue un get per un'entità con una relazione molti-a-uno con join esterno impostato su true, non trovato impostato su ignorato e la riga di entità su un lato non esiste, NHibernate esegue una selezione aggiuntiva tentando di caricarlo anche se la selezione precedente che era stata appena eseguita non riusciva a trovarla.

Domanda

Perché questa selezione extra viene eseguita ed esiste un modo per eliminarla?

Contesto

Sto lavorando con un database legacy senza vincoli di chiave esterna in cui non ho alcun controllo sullo schema. La modifica è sfortunatamente fuori discussione. Tieni presente che i miei mapping effettivi sono più complessi di così. Ciò si verifica più volte per l'entità reale e spesso vengono caricati da ICriteria.List<T>() e non Session.Load<T>(id), causando molte query non necessarie e un notevole aumento delle prestazioni.

Esempio semplificato


Codice
ISession Session = ...
...
Session.Get<Bid>(1);
...
SQL eseguito
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
Mappatura
<?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>  
Contenuto della tabella delle offerte
Id  ItemId    
1   222  
Contenuto della tabella degli articoli
Id  
333  
444  
È stato utile?

Soluzione

OK, sembra che sia sicuramente un bug in NHibernate, come puoi vedere qui . Al momento, è contrassegnato come minore, quindi immagino che votarlo potrebbe aumentare il suo profilo e ottenere una soluzione.

Altri suggerimenti

Senza impostarlo, immagino che la chiave sia sostituire il outer-join = " true " con fetch = " join " nell'associazione molti-a-uno. Per impostazione predefinita, la modalità di recupero di un'associazione molti-a-uno è & Quot; selezionare & Quot ;, e sospetto che ciò stia causando l'esecuzione della selezione.

Se modifichi tale mappatura in modo che sia:

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

dovrebbe comportarsi più come ti aspetti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top