Domanda

Mi chiedo come si possa eliminare un'entità avente solo il suo ID e tipo (come nella mappatura) utilizzando NHibernate 2.1?

È stato utile?

Soluzione

Se utilizzi il caricamento lento, Load crea solo un proxy.

session.Delete(session.Load(type, id));

Con NH 2.1 puoi usare HQL.Non sono sicuro di come sia effettivamente, ma qualcosa del genere: tieni presente che questo è soggetto a SQL injection - se possibile, utilizzare invece query parametrizzate con SetParameter()

session.Delete(string.Format("from {0} where id = {1}", type, id));

Modificare:

Per Load, non è necessario conoscere il nome della colonna Id.

Se hai bisogno di saperlo, puoi ottenerlo tramite i metadati NH:

sessionFactory.GetClassMetadata(type).IdentifierPropertyName

Un'altra modifica.

session.Delete() sta istanziando l'entità

Quando si utilizza session.Delete(), NH carica comunque l'entità.All'inizio non mi piaceva.Poi ho capito i vantaggi.Se l'entità fa parte di una struttura complessa che utilizza ereditarietà, raccolte o riferimenti "qualsiasi", in realtà è più efficiente.

Ad esempio, se class A E B entrambi ereditano da Base, non tenta di eliminare i dati nella tabella B quando l'entità effettiva è di tipo A.Ciò non sarebbe possibile senza caricare l'oggetto reale.Ciò è particolarmente importante quando sono presenti molti tipi ereditati, ciascuno composto anche da molte tabelle aggiuntive.

La stessa situazione si verifica quando si dispone di una raccolta di Bases, che sono tutte istanze di A.Quando si carica la collezione in memoria, NH sa che non è necessario rimuoverne alcuna B-cose.

Se l'entità A ha una collezione di Bs, che contiene Cs (e così via), non tenta di eliminarne nessuno Cs quando la raccolta di Bs è vuoto.Questo è possibile solo leggendo la raccolta.Ciò è particolarmente importante quando C è complesso di per sé, aggregando ancora più tabelle e così via.

Quanto più complessa e dinamica è la struttura, tanto più efficiente è caricare i dati effettivi invece di eliminarli "alla cieca".

Le eliminazioni HQL presentano insidie

HQL elimina per non caricare i dati in memoria.Ma le eliminazioni HQL non sono così intelligenti.Fondamentalmente traducono il nome dell'entità nel nome della tabella corrispondente e lo rimuovono dal database.Inoltre, elimina alcuni dati di raccolta aggregati.

Nelle strutture semplici, questo può funzionare bene ed efficiente.Nelle strutture complesse, non tutto viene cancellato, il che porta a violazioni dei vincoli o "perdite di memoria del database".

Conclusione

Ho anche provato a ottimizzare la cancellazione con NH.Nella maggior parte dei casi ho rinunciato, perché NH è ancora più intelligente, "funziona e basta" e di solito è abbastanza veloce.Uno degli algoritmi di eliminazione più complessi che ho scritto è l'analisi delle definizioni di mappatura NH e la creazione di istruzioni di eliminazione da esse.E, nessuna sorpresa, non è possibile senza leggere i dati dal database prima di eliminarli.(L'ho appena ridotto per caricare solo le chiavi primarie.)

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