C # relazione molti a molti
Domanda
Così, ho bisogno di qualche modo per attuare una non orientato rete (credo che questo è il termine corretto) in C #
Diciamo che ho i seguenti dati:
Foo1 <-> Bar1
Foo2 <-> Bar1
Foo2 <-> Bar2
Foo2 <-> Bar3
Foo3 <-> Bar2
Foo3 <-> Bar3
Come potrei implementare qualcosa che potesse sostenere questo?
Un modo per farlo sarebbe quello di creare una classe che contiene un Foo, e un bar, e per il mio esempio mi piacerebbe avere 6 di questi, con ogni possibile combinazione, tuttavia questo raddoppia il backup dei dati.
Con questi dati, ho bisogno di essere in grado di eseguire calcoli su foo1 in base a quanti bar di esso punti troppo, e quanti Foo del punto della barra troppo ecc ecc.
Non sto cercando una risposta, io preferirei una direzione su come realizzare questo, forse anche un po 'di link.
Soluzione
Hai praticamente delineato un modello grafico, tradizionalmente pensato come 'nodi' e 'bordi'. Ma i titoli / prestiti funziona.
Ci sono due risposte classiche a questo genere di cose.
Dipende da quello che le domande che vuole essere in grado di chiedere i dati, l'efficienza si desidera memorizzare, e come denso tuoi dati sono.
Se, per esempio, il 30% delle possibili relazioni fra titoli e impieghi esiste, quindi una struttura di dati densa sarà sicuramente pagare. Basta tenere una grande matrice di:. Titoli su X. Prestiti su Y. (X, Y) significa che esiste il prestito
Se il set non è molto denso, poi si inizia con "strutture di dati bordo sparse." A seconda dell'applicazione, si potrebbe:
-
Ogni oggetto S ha un elenco di è Ls.
{ S->L,L,L; S->L; S->L,L,L }
. Rende veramente facile da trovare i vicini di S, ma difficile da trovare L's -
oggetti S hanno un elenco di Ls, Ls avere una lista di S di: (
S->L,L,L
eL->S,S,S
). Utilizza più spazio, ma ti dà query entrambi-direzionali. -
Conservare una serie di soli coppie (
S,L
). Piuttosto male a meno che per lo più bisogno di chiedere "sono questo S e L e che correlate?" -
memorizzare un elenco di entrambi
S,L
eL,S
e l'indice in qualche modo. Questo è ciò che intendiamo per "rendere il vostro database di fare il lavoro".
Vedere anche Struttura dei dati per i rapporti
Altri suggerimenti
Bene, senza dare una risposta, pensare a che cosa può essere fatto con 2-dimensionale array e pensare al problema dal punto di vista di memorizzare informazioni sui bordi.
Questa puzza come un problema del database relazionale a me. Quello che hai descritto è di due tabelle con una relazione molti-a-molti. Se questa risposta è appropriata dipenderà molto su ciò che i vostri dati appare in realtà come. La precedente proposta di avere ogni oggetto contiene un elenco di l'altro oggetto è un modo, ma chiamiamolo cose col loro nome, questo è un database relazionale. Considerare l'utilizzo di una tecnologia come il quadro ADO.Net Entity o LINQ per definire i dati come un database relazionale e utilizzare LINQ per interrogare i dati.
Si parla che siete preoccupati per il raddoppio della memoria. Anche in questo caso dipende da ciò che i dati del mondo reale sembra, ma se non hai grandi quantità di dati, questo è probabilmente non sarà un problema. L'unica memoria sprecata è memoria vuota. Utilizzare la memoria, se (a) rende il problema più facile da risolvere o (b) ti dà più flessibilità. Non ottimizzare se non si ha un problema di prestazioni.
ogni classe potrebbe avere un elenco del tipo dell'altro. Tu non duplicare i dati in questo modo a meno che non si sta utilizzando i tipi di valore. i riferimenti incrociati potrebbero fare per le perdite di memoria.
Quello che Joe ha detto è sulla strada giusta. Ogni prestito avrebbe un elenco di istanze di sicurezza e di ogni sicurezza avrebbe un elenco di istanze di prestito. Il trucco è quello di assicurarsi che non hai mai un prestito che pensa che sia connesso ad un Security, ma che la sicurezza non è d'accordo. Vorrei suggerire che permette aggiungere o rimuovere le operazioni solo su coppie, per garantire che hanno finito in parallelo. Non vedo come questo possa causare perdite di memoria, dal momento che il GC è abbastanza intelligente per gestire questa situazione. Riferimento-conteggio, al contrario, non può gestire questo senza alcuni trucchi.