Mam standardową relację wiele do wielu w mojej bazie danych między osobą a widżetem. Osoba pełniąca rolę administracyjną ma dostęp do WSZYSTKICH widżetów. W mojej aplikacji chcę zobaczyć, do których widżetów dana osoba ma dostęp.

Mam dwie opcje wysokiego poziomu:

  1. Jawnie zarządzaj relacjami. Kiedy osoba staje się administratorem, powiąż ją ze wszystkimi istniejącymi widżetami. Po utworzeniu widżetu powiąż go ze wszystkimi istniejącymi administratorami.

  2. W czasie wykonywania, jeśli osoba jest administratorem, załóż, że ma dostęp do WSZYSTKICH widżetów i pomija tabelę relacji podczas ładowania widżetów.

Czy jedna opcja jest lepsza od drugiej? Czy istnieje nazwa tego scenariusza?

Próbowałem zastosować opcję 2 za pomocą NHibernate i nie mogę znaleźć sposobu, aby ominąć tabelę relacji podczas ładowania wszystkich widżetów dla jednostki (a nawet gdybym mógł, niepotrzebnie załadowałoby to dużo informacji, chyba że Widgety ładuję oddzielnie od encji Osoba i stosuję stronicowanie).

0
Mayo 22 lipiec 2011, 01:56

2 odpowiedzi

Najlepsza odpowiedź

Zmapowałbym to za pomocą ról.

Role: Osoba = 1: Wiele

Więc kiedy tworzysz osobę, tworzysz również nową rolę, chyba że jest to administrator, w którym to przypadku używa istniejącej roli administratora.

Wtedy problem jest prosty: potrzebujesz tabeli WidgetRole.

Po utworzeniu nowego widgetu i automatycznym dodaniu wpisu do tabeli WidgetRole dla NewWidget, AdminRole

Gdy osoba zmieni rolę administratora, po prostu zmień jej aktualną rolę.

Imo ta konfiguracja jest logicznie prostsza niż posiadanie specjalnego przypadku administratora.

1
BonyT 22 lipiec 2011, 02:04
Person-Widget jest poza moją kontrolą — ale mogę dodać relację Role-Widget i mieć właściwość Person, która łączy oba zestawy. Żadnych sztuczek NHibernate i pozostawia dużo miejsca na dostrojenie w przyszłości.
 – 
Mayo
22 lipiec 2011, 08:25

Musiałem podzielić się ostatecznym rozwiązaniem - powinno pomóc każdemu, kto próbuje zmusić NH do załadowania relacji, która nie jest jasno określona w DB.

Już tworzyłem podklasy osoby, a NHibernate jest wystarczająco sprytny, aby rozpoznać Administratora: Osoba i utworzyć instancję tej Osoby jako Administratora (gdzie Administrator ma tabelę z PK/FK PersonId)

Właśnie dodałem nowe nadpisanie mapowania dla administratora...

mapping.HasManyToMany(x => x.Widgets)
  .Table("AdministratorWidgetAccess")
  .Cascade.None();

I dodałem widok o nazwie AdministratorWidgetAccess...

SELECT a.PersonId as [AdministratorId], w.WidgetId as 
FROM dbo.Administrator AS a LEFT OUTER JOIN
  dbo.Widget AS w ON 1 = 1

Podczas działania, jeśli osoba jest administratorem, ładuje wszystkie widżety na podstawie relacji w widoku, w przeciwnym razie ładuje widżety na podstawie tabeli łączenia.

0
Mayo 22 lipiec 2011, 19:44