5

Mam trochę kłótni z moim współpracownikiem, którego nie mogę znaleźć na razie, ale to jest bardzo podstawowe.Nawiązanie relacji jeden do wielu z Fluent Nhibernate

Nawiązywanie relacji jeden-do-wielu w elemencie Fluent Nhibernate.

Weźmy na przykład role i użytkowników. Rola może być przypisany do wielu użytkowników, więc zrobiłem moje wnętrzności podmiot wygląda następująco:

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

i roli

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

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

Jak widać jestem przedstawieniu zbiór użytkowników w rolach, rodzaj mówiąc, że każda rola będzie miała wielu użytkowników. Podmiot użytkownika ma odniesienie do jednostki ról, niezbędne do określenia, do której roli należy użytkownik.

Moim zdaniem jest to poprawny sposób linkowania, a mój współpracownik mówi, że posiadanie referencji Role dla użytkowników spowoduje utworzenie odwołania cyklicznego. Kto ma rację?

Próbowałem znaleźć odpowiedź przez Internet. Myślę, że to pytanie mówi mi, że mam rację: Fluent NHibernate Many to one mapping

Ale potem spojrzałem na projekt próbki Fuent NHibernate tutaj https://github.com/jagregory/fluent-nhibernate/tree/master/src/Examples.FirstAutomappedProject/Entities i nie mam przykład co usiłuję do wdrożenia. Czy możecie doradzić lub pomóc mi znaleźć dokument wyjaśniający prawidłowy sposób? Czy mam rację? Dziękuję.

Odpowiedz

12

To, co tu proponujesz, jest całkowicie możliwe i dopuszczalne w ramach nHibernate. Oczywiście wymieniłeś modele zamiast plików odwzorowujących, ale Fluent nHibernate pozwala skonfigurować tak samo odwzorowania bez problemu.

Niezależnie od tego, czy rzeczywiście zdecydujesz się zamapować związek w ten sposób, zależy to wyłącznie od osobistych preferencji i konkretnego scenariusza. W ten sposób zmapowałem modele, ale również nie zdecydowałem się, głównie dlatego, że w niektórych przypadkach nie ma sensu nadmiernie komplikować wykresu obiektów. Weźmy na przykład tabelę przeglądową (np. Culture lub Locale), która jest wielokrotnie przywoływana w wielu tabelach w bazie danych, podczas mapowania tego miałbym właściwość Culture w każdym z modeli nadrzędnych, ale nie miałaby kolekcji obiektów nadrzędnych w modelu Kultura - to po prostu nie ma sensu.

Należy również rozważyć ładowanie danych za pośrednictwem warstwy trwałości - jeśli tworzysz tego rodzaju relacje i potrzebujesz tylko prostej listy ról, które musisz wziąć pod uwagę, lub jeśli kolekcja użytkowników jest wypełniona - możesz określić chętnych lub późne ładowanie, ale z mojego doświadczenia wynika, że ​​sprecyzowanie ładowania za pomocą odpowiedniego polecenia Fetch w Zapytaniach może spowodować bardziej zoptymalizowane wywołanie do bazy danych.

Zasadniczo mówię, że nie ma absolutnej "właściwej drogi" przy podejmowaniu decyzji o definiowaniu mapowań - naprawdę trzeba zrównoważyć model bogaty obiekt vs. wydajność kwerendy, ale twój konkretny przykład jest całkowicie do przyjęcia, jeśli potrzebuję tego.

Właśnie przeczytałem twoje pytanie i nie jestem pewien, czy pytasz również o przykłady odwzorowań skonfigurowanych w ten sposób, więc jeśli chcesz podać kilka przykładów, daj mi znać, a ja przygotuję dla ciebie kilka.

Aby osiągnąć relację pan opisać musisz następujące klasy map (Dodałem właściwości ID jako Chyba masz tych):

Dla ról:

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")); 
    } 
} 

dla użytkowników:

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"); 
    } 
} 

nie będę zbyt rozłączyła się na „metodę vs ich metody” - powyższe jest całkowicie dopuszczalne i zależy od wymagań, gdy przyjdziesz do korzystania o bject model w twoim kodzie. Ewentualnie, jeśli nie chcesz, aby kolekcja Użytkownicy w mapie ról usunęła tę właściwość i powiązaną deklarację mapowania HasMany. Warto zauważyć, że specyfikacja .Inverse() delegowała zarządzanie relacją między rolą a użytkownikiem do encji Użytkownicy, co ma sens jako zasadniczo proces dodawania lub edytowania istniejącego użytkownika i dostarczania RoleId nawiąże związek.

Nadzieja to pomaga nieco, jeśli masz jakieś bardziej szczegółowe pytania daj mi znać

+0

Będę bardzo wdzięczny, jeśli można pokazać mi przykład rodzaju „mój sposób vs inne sposoby”. – Shenaniganz

+0

Nie ma problemu, opublikuję kilka przykładów później dla ciebie – CSL

+1

Zaktualizowałem moją odpowiedź, aby dołączyć kilka przykładowych map dla ciebie – CSL