NHibernate esegue istruzioni select estranee
-
06-07-2019 - |
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
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.