fbpx
devstyle.pl - Blog dla każdego programisty
devstyle.pl - Blog dla każdego programisty
2 minut

Mapowanie Fluent NHibernate i enum


23.11.2009

Jeśli taką klasę:

  1:  public enum Gender
  2:  {
  3:  	Male = 1,
  4:  	Female,
  5:  }
  6:  
  7:  public class User
  8:  {
  9:  	public virtual int Id { get; set; }
 10:  	public virtual string UserName { get; set; }
 11:  	public virtual Gender Gender { get; set; }
 12:  }
 13:  

zmapujemy całkowicie standardowo:

  1:  public class UserMap : ClassMap<User>
  2:  {
  3:  	public UserMap()
  4:  	{
  5:  		Id(x => x.Id);
  6:  		Map(x => x.UserName);
  7:  		Map(x => x.Gender);
  8:  	}
  9:  }

to w bazie zobaczymy wartości enuma Gender:

INSERT INTO Users (UserName, Gender) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 'username', @p1 = 'Male'

W wielu przypadkach może być to zjawisko pożądane, ale czasami może chodzić nam o coś innego. To "czasami" odnosi się na przykład do sytuacji, w której mamy osobną tabelę "Genders" z dwoma wartościami: 1|Male, 2|Female. Wówczas w tabeli Users chcielibyśmy mieć również 1 i 2, a nie tekstowe odpowiedniki.

Rozwiązanie jest banalne, wystarczy że zmodyfikujemy mapowanie wykorzystując metodę CustomType<T>():

  1:  public class UserMap : ClassMap<User>
  2:  {
  3:  	public UserMap()
  4:  	{
  5:  		Id(x => x.Id);
  6:  		Map(x => x.UserName);
  7:  		Map(x => x.Gender).CustomType<Gender>();
  8:  	}
  9:  }

Efekt:

INSERT INTO Users (UserName, Gender) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 'username', @p1 = 1

Minitip, ale kilka chwil kiedyś na to straciłem.

0 0 votes
Article Rating
3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
^simon
15 years ago

Interesujące… Osobiście używam zwykłych plików XML, ponieważ nie wymagają niczego dodatkowego. Co mnie zdziwiło to fakt, że w mapowaniach XML domyślnie enumy mapowane są na ich reprezentacje numeryczne, podczas gdy w FlueenHHib — na stringi. Ciekawe skąd ta zmiana podejścia… W każdym razie dzięki za ostrzeżenie — ja tam wole numerki, więc w razie czego (przejścia na Fluent) będę wiedział co robić.

Gutek
15 years ago

a no wlasnie, dopiero 2 krotne przestudiowanie komentarza simona zwrocilo moja uwage na tytul bo tak troche nie kumalem skoro jest to w konfigu ;)

dzieki za info, mimo wszystko niestety sadze, ze nie przekonam swoich do fluent ;) jak nie moge do nowszej wersji castla. Moze w innym projekcie :)

Gutek

biz
biz
15 years ago

Ja podobnie jak simon używam klasycznego mapowania bazującgo na plikach XML. Każde z przedstawionych rozwiązań mapowania typu wyliczeniowego nie jest do końca satysfakcjonujące dla mnie. Dobrze, aby typ wyliczeniowy mógł posiadać trzy "atrybuty" opisujące go: nazwę, ładną nazwę oraz wartość najlepiej jako stałej długości string. Niestety, aby coś takiego było możliwe trzeba samemu sobie zasymulować działanie enuma-a, np. na klasie statycznej.
Mapowanie enuma do bazy jako string ma tę wadę, że nie do końca wiadomo jak ustalić rozmiar kolumny varchar(?), char(?) i trzeba się tu pilnować.
Mapowanie wartości liczbowej natomiast może okazać się koszmarem przy pisaniu zapytań SQL-owych. Przecież czasem pomimo używania O/R mappingu zdarza się nam pisanie zapytań SQL, np. w celach wygenerowania większych raportów.
Napewno lepiej wygląda to:
SELECT * FROM FAKTURY f WHERE f.TYP_FAKTURY = ‘S’ AND f.STATUS_FAKTURY = ‘Z’
niż to:
SELECT * FROM FAKTURY f WHERE f.TYP_FAKTURY = 1 AND f.STATUS_FAKTURY = 3

Kurs Gita

Zaawansowany frontend

Szkolenie z Testów

Szkolenie z baz danych

Książka

Zobacz również