2010-03-09 18 views
5

È possibile eseguire una ricerca inversa globale sugli oggetti gestiti da NHibernate?Riferimenti di oggetti di ricerca globali in NHibernate

In particolare, ho una classe persistente chiamata "Io". Ci sono un numero enorme di campi su più tabelle che possono potenzialmente contenere un oggetto di quel tipo. C'è un modo (data un'istanza specifica di un oggetto Io), per recuperare una lista di oggetti (di qualsiasi tipo) che effettivamente fanno riferimento a quell'oggetto specifico? (Punti bonus se è in grado di identificare quali campi specifici contengono effettivamente il riferimento, ma non è critico.)

Poiché i mapping NHibernate definiscono tutti i collegamenti (e il database sottostante ha corrispondenti collegamenti di chiave esterna), dovrebbe essere qualche modo per farlo.

Immaginate questo tipo di struttura:

class Io 
{ 
    public int Id { get; set; } 
    // other fields specific to the Io type 
} 

class ThingOne 
{ 
    public int Id { get; set; } 
    public Io SensorInput { get; set; } 
    public Io SolenoidOutput { get; set; } 
    // other stuff 
} 

class ThingTwo 
{ 
    public int Id { get; set; } 
    public Io SensorInput1 { get; set; } 
    public Io SensorInput2 { get; set; } 
    public SubThing Doohickey { get; set; } 
    // ... 
} 

class SubThing 
{ 
    public int Id { get; set; } 
    public Io ControlOutput1 { get; set; } 
    // ... 
} 

Data una specifica istanza di Io, voglio scoprire che è riferimento la ThingTwo con id 12. o che è riferisce a questo e anche dal ThingOne con id 16. Se possibile, anche che il primo riferimento è tramite SensorInput2, ad esempio.

risposta

3

Bene, i mapping di configurazione non sembrano esporre la relazione FK quindi per il momento qualche riflessione può trovare quale tipo di riferimento . Si noti che il codice sottostante presuppone che tutte le classi associate a nhibernate siano associate a un singolo assieme e che utilizzi anche C# 3.0 e versioni successive per il supporto LINQ.

IO toSearch = nhSession.Get<IO>(5); 
var assembly = Assembly.Load("EntityAssembly"); 
IList<Type> assemblyTypes = assembly.GetTypes(); 
var searchType = toSearch.GetType(); 
var typesThatContainedSearchTypeProperty = 
    assemblyTypes.Where(
    ast => ast.GetProperties().Count() > 0 && 
    ast.GetProperties().Where(
     astp => astp.PropertyType != null && astp.PropertyType == searchType).Count() > 0); 

Ora, se anche voi volete ottenere gli oggetti che contengono questa particolare istanza di IO si può avere un bel multicriteriale di farlo in un unico viaggio di andata.

var multiCrit = nhSession.CreateMultiCriteria(); 

foreach (var type in typesThatContainedSearchTypeProperty) 
{ 
    //maybe this class has multiple properties of the same Type 
    foreach (PropertyInfo pi in type.GetProperties().Where(astp => astp.PropertyType == toSearch.GetType())) 
     multiCrit.Add(nhSession.CreateCriteria(type).Add(Restrictions.Eq(pi.Name, toSearch))); 
} 
IList results = multiCrit.List(); 

come si può intuire, dal momento che si comincia con la riflessione possiamo finire solo con la riflessione. L'elenco dei risultati è un array con ogni voce il risultato di ciascun criterio, in cui ogni ricerca di criteri può essere un singolo risultato o un elenco di risultati.

+0

All'inizio questo mi ha dato qualche problema, ma si è rivelato un errore nelle mie mappature hbm. Dopo aver appiattito il risultato in una singola lista, questo fa esattamente quello che cercavo. Grazie! – Miral

+0

È così bello, ma uno dovrebbe essere a conoscenza di ** toSearch.GetType() **. Può restituire l'oggetto proxy invece di quello reale. –

+0

@ S.M.Amin si sta mescolando Get() con Load().Get() non restituirà un proxy, Load() sarà – Jaguar

0

La classe "lo" non contiene un riferimento agli oggetti che contengono gli oggetti "lo"?

cioè se "Lo" è di riferimento per un determinato numero di "HI" oggetti:

public class Lo 
{ 
    List<Hi> hiObjects; 
} 

Ora, se si dispone di un caso di "Lo":

Lo lo = new Lo(); 
List<Hi> hiObjects = lo.hiObjects; 

Se non hanno questo tipo di riferimenti, potresti aggiungerli.

+0

Solo se c'è un modo per NHibernate per riempire quelle informazioni per me. Sicuramente non appartiene allo stato persistente - si tratta di informazioni recuperate come parte della costruzione del grafico dell'oggetto. Ho ampliato la mia domanda con un esempio che, si spera, spiega meglio le cose. – Miral

+0

Inoltre, al conteggio corrente ci sono circa 20 diversi tipi che potrebbero contenere un Io. Quindi davvero non voglio doverli elencare esplicitamente ovunque. – Miral

Problemi correlati