5

Ho un po 'di discussione con il mio collega che non riesco a trovare una risposta a questo è roba molto di base.Impostazione di uno a molti rapporti con Fluent Nhibernate

Stabilire una relazione uno a molti nell'entità Fluent Nhibernate.

Prendiamo ad esempio ruoli e utenti. Un ruolo può essere assegnato a più utenti così ho fatto il mio coraggio entità assomiglia:

public class User 
{ 
    [Required] 
    public virtual string FirstName { get; set; } 
    public virtual Role Role { get; set; } 
} 

e il ruolo

public class Role 
{ 
    [Required] 
    public virtual string Name { get; set; } 
    public virtual IList<User> Users{ get; set; } 

    public Role() 
    { 
     Users = new List<Users>(); 
    } 
} 

Come potete vedere sto riferimento a un insieme di utenti in ruoli, tipo di dicendo che ogni ruolo avrà più utenti. L'entità utente ha quel riferimento di entità ruolo necessario per identificare a quale ruolo appartiene un utente.

A mio parere questo è il modo corretto per collegare e il mio collega dice che avere un riferimento per gli utenti creerà un riferimento circolare. Chi ha ragione?

Ho provato a trovare la risposta online. Credo che questa domanda mi dice che ho ragione: Fluent NHibernate Many to one mapping

Ma poi ho guardato un progetto di esempio Fuent NHibernate qui https://github.com/jagregory/fluent-nhibernate/tree/master/src/Examples.FirstAutomappedProject/Entities e io non faccio un esempio di quello che sto cercando di attuare. Potete consigliare o aiutarmi a trovare un documento che spieghi il modo corretto? Ho ragione? Grazie.

risposta

12

Ciò che state proponendo qui è interamente possibile e consentito all'interno della struttura di nibibli. Ovviamente hai elencato i modelli piuttosto che i file di mappatura ma Fluent nHibernate ti consente di configurare i tuoi mapping in questo modo senza problemi.

Se in realtà si sceglie di mappare una relazione in questo modo dipende interamente dalle preferenze personali e dallo scenario specifico. Ho mappato i modelli in questo modo, ma ho anche scelto di non farlo, principalmente perché in alcuni casi non ha senso complicare eccessivamente il grafico dell'oggetto. Prendiamo ad esempio una tabella di ricerca (ad esempio Cultura o Locale) a cui si fa riferimento più volte su più tabelle in un database, quando si mappano questo avrei una proprietà Cultura in ciascuno dei modelli padre ma non avrebbe collezioni di oggetti padre nel modello Cultura - non ha senso.

È inoltre necessario considerare il caricamento dei dati tramite il livello di persistenza - se si crea questo tipo di relazione e si richiede solo un semplice elenco di ruoli da considerare quando, o se, la raccolta di utenti è popolata - è possibile specificare desiderosi o caricamento in ritardo, ma nella mia esperienza specificando caricamento avido con un comando Fetch corrispondente nelle query può risultare in una chiamata più ottimizzata al database.

Fondamentalmente quello che sto dicendo è che non esiste un "modo corretto" assoluto nel decidere come definire le mappature - è davvero necessario bilanciare un modello di oggetto ricco con prestazioni di query, ma il tuo esempio specifico è perfettamente accettabile se si bisogno di essa.

Ho appena riletto la tua domanda e non sono sicuro che tu stia anche chiedendo esempi di mappature configurate in questo modo, quindi se vuoi alcuni esempi fammelo sapere e metterò un po 'insieme per te.

Per raggiungere il rapporto si descrive si avrebbe bisogno le seguenti classi di mappa (ho aggiunto proprietà ID come immagino si dispone di quelli):

per i ruoli:

public class RoleMap : ClassMap<Role> 
{ 
    public RoleMap() 
    { 
      Table(@"Roles"); 
      Id(x => x.Id).GeneratedBy.Assigned(); 
      Map(x => x.Name).Column("Name"); 
      HasMany<User>(x => x.Users) 
      .Inverse() 
      .KeyColumns.Add("RoleId", mapping => mapping.Name("RoleId")); 
    } 
} 

per gli utenti:

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
      Table(@"Users"); 
      Id(x => x.Id).GeneratedBy.Assigned(); 
      Map(x => x.FirstName); 
      Map(x => x.RoleId);  
      References(x => x.Role) 
      .Class<Role>() 
      .Columns("RoleId"); 
    } 
} 

non avrei avuto troppo appeso su "il metodo vs il loro metodo" - quanto sopra è perfettamente accettabile, e dipende dalle vostre esigenze quando si arriva a usare l'o modello di bject nel tuo codice. In alternativa, se non si desidera una raccolta di utenti nella Mappa dei ruoli, rimuovere la proprietà e la dichiarazione di associazione HasMany associata. Una cosa da notare da quanto sopra è che la specifica .Inverse() ha delegato la gestione della relazione tra un ruolo e un utente all'entità Users, che ha senso come fondamentalmente il processo di aggiunta o modifica di un utente esistente e fornitura di un RoleId forgia la relazione.

Spero che questo aiuti un po 'se avete domande più specifiche fatemi sapere

+0

Le sarei molto grato se mi potesse mostrare un esempio di una sorta di "il mio modo vs gli altri modi". – Shenaniganz

+0

Nessun problema, posterò alcuni esempi più tardi per te – CSL

+1

Aggiornato la mia risposta per includere un paio di mappe campione per te – CSL

Problemi correlati