Domanda

Sono relativamente nuovo su NHibernate, ma lo sto usando da alcuni programmi e ne sono innamorato. Sono arrivato a una situazione in cui ho bisogno di aggregare i dati da 4-5 database in un unico database. In particolare si tratta di dati di numeri di serie. Ogni database avrà il proprio file di mappatura, ma alla fine tutte le entità condividono la stessa struttura di base (classe seriale).

Comprendo che NHibernate desidera un mapping per classe, quindi il mio pensiero iniziale era di avere una classe seriale di base e quindi ereditarla per ogni diverso database e creare un file di mapping univoco (la classe ereditata avrebbe zero contenuto). Questo dovrebbe funzionare alla grande per afferrare tutti i dati e popolare gli oggetti. Quello che vorrei fare è salvare queste classi ereditate (non sono sicuro di quale sia il termine corretto) nella tabella delle classi di base usando il mapping delle classi di base.

Il problema è che non ho idea di come forzare NHIbernate a utilizzare un file di mapping specifico per un oggetto. Trasmettere la classe ereditata alla classe base non fa nulla quando si usa 'session.save ()' (si lamenta di non mappare).

C'è un modo per specificare esplicitamente quale mappatura usare? O c'è solo qualche preside OOP che mi manca per lanciare in modo più specifico una classe ereditata sulla classe base? O questa idea è solo una cattiva.

Tutte le cose sull'eredità che ho trovato in merito a NHibernate (capitolo 8) non sembrano essere totalmente applicabili a questa funzione, ma potrei sbagliarmi (la tabella per classe di calcestruzzo sembra forse utile, ma Non riesco a farcela completamente con riguardo a come NHibernate capisce cosa fare).

È stato utile?

Soluzione

Non so se questo possa essere d'aiuto, ma sostanzialmente non proverei a farlo.

In sostanza, penso che potresti soffrire di "golder hammer" sindrome: quando hai un martello DAVVERO DAVVERO bello (cioè Hibernate (e condivido la tua opinione su di esso; è uno strumento MAGNIFICO)), tutto sembra un chiodo.

In genere cerco semplicemente di avere una "conversione manuale" classe, ovvero quella che ha costruttori che prendono le classi di ibernazione per le tue singole classi seriali e che semplicemente copia i dati nel proprio formato specifico; quindi Hibernate può semplicemente serializzarlo nel (singolo) database usando la propria mappatura.

In effetti, il motivo per cui penso che questa sia una soluzione migliore è che ciò che stai effettivamente cercando di fare è avere una serializzazione asimmetrica nella tua classe; cioè leggi da un database nella tua classe derivata, scrivi in ??un altro database nella tua classe base. Niente di troppo orribile, in realtà, tranne che è fondamentalmente un processo unidirezionale; se vuoi davvero la conversione da un database all'altro, fai semplicemente la conversione e finisci con esso.

Altri suggerimenti

Questo potrebbe aiutare;

Uso di NHibernate con più database

Dall'articolo;

  

Introduzione

     

...   descritto usando NHibernate con   ASP.NET; ha offerto linee guida per   comunicare con un singolo database.    Ma a volte è necessario   comunicare con più database   contemporaneamente. Per fare NHibernate   questo, deve esistere una factory di sessione   per ogni database che sarai   comunicare con. Ma, come spesso accade   il caso con più database, alcuni   dei database sono usati raramente. Così   potrebbe essere una buona idea non creare   fabbriche di sessione fino a quando non lo sono   effettivamente necessario. Questo articolo riprende   dove il precedente NHibernate con   L'articolo di ASP.NET è stato lasciato fuori e descrive   i dettagli di attuazione di questo   approccio dal suono semplice. sebbene il   articolo precedente incentrato su ASP.NET,   il suggerimento seguente è supportato in   sia ASP.NET che .NET.

     

...

     

La prima cosa da fare quando si lavora   con più database è   configurare comunicazioni adeguate.   Crea un file di configurazione separato per ciascuno   database, metterli tutti in una centrale   cartella di configurazione, quindi fare riferimento a loro   dal web / app.config.

     

...

Non sono sicuro al 100% che questo farà ciò di cui ho bisogno, ma oggi ho trovato questo google su NHibernate e tipi anonimi:

http://infozerk.com/ averyblog / refactoring-con-oggetto-costruttori-in-HQL-con-NHibernate /

La parte interessante (per me sono nuovo in questo) è la parola chiave "nuova" nella clausola di selezione HQL. Quindi quello che potrei fare è selezionare SerialX da DatabaseX usando mappingX e passarlo a un costruttore per SerialY (il seriale generale / base). Quindi ora ho generato SerialY da mappingX / databaseX e (si spera) potrei quindi session.save e NHibernate userà mappingY / databaseY.

La ragione per cui mi piace semplicemente non avere due classi con gli stessi dati persistenti (credo!). Non c'è davvero alcuna differenza funzionale tra questo e la restituzione di un elenco di SerialX, iterando attraverso di esso e generando SerialY e aggiungendolo a un nuovo elenco (la prima e migliore risposta fornita).

Questo non ha il vantaggio più generale di creare casi utili per le mappature NHibernate con ereditarietà, ma penso che farà le cose limitate che desidero.

Sebbene sia vero, avrai bisogno di un file / classe di mappatura per ognuna di quelle tabelle, non c'è nulla che ti impedisca di rendere tutte quelle classi implementano un'interfaccia comune.

È quindi possibile aggregarli tutti insieme in un'unica raccolta nel livello dell'applicazione (ovvero Elenco) in cui ciascuna di queste classi implementa Elenco)

Probabilmente dovrai scrivere un po 'di idraulica per tenere traccia della sessione in cui archiviarla (poiché stai prendendo di mira più database) se desideri effettuare aggiornamenti. Ma il processo per farlo varierà in base al modo in cui hai impostato le cose.

Ho scritto un post molto lungo con codice e tutto il resto per rispondere a Dan. Alla fine penso di aver perso l'ovvio.

public class Serial
{
    public string SerialNumber {get; set;}
    public string ItemNumber {get; set;}
    public string OrderNumber {get; set;}
}

...

Serial serial = sessionX.get(typeof(Serial), someID);
sessionY.save(serial);

NHibernate dovrebbe usare mappingX per get e mappingY per il salvataggio poiché le sessioni non vengono condivise e il mapping è legato alla sessione. Quindi posso avere 2 mappature che puntano alla stessa classe perché in ogni sessione particolare c'è una sola relazione tra mappatura e classe.

Almeno penso che sia il caso (impossibile testare atm).

Purtroppo questo caso specifico è davvero noioso e non utile. In un programma diverso dello stesso dominio derivano dalla classe base per una parte specifica della logica aziendale. Non volevo creare un file di mappatura poiché era solo per rendere più semplice un piccolo pezzo di codice. Comunque, non sono riuscito a farlo funzionare in NHibernate per gli stessi motivi della mia prima domanda e ho fatto il metodo descritto da McWafflestix per aggirare il problema (dato che era minore).

Detto questo, l'ho trovato tramite Google:

http://jira.nhibernate.org/browse/NH-662

Questa è esattamente la stessa situazione e sembra (possibilmente) risolta in NH 2.1+? Non ho ancora dato seguito.

(nota: Dan, nel mio caso sto ricevendo da diversi db, scrivendo solo a uno. Sono ancora interessato al tuo suggerimento sull'interfaccia perché penso che sia una buona idea per altri casi. Definiresti il mappatura rispetto all'interfaccia? Se provo a salvare una classe che implementa l'interfaccia che non ha una definizione di mappatura, NHibernate userebbe la mappatura dell'interfaccia? O dovrei dichiarare sottoclassi vuote nella mappatura per ogni classe che implementa l'interfaccia mappatura?)

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