Mapowanie Fluent NHibernate i enum

23 listopada 2009 06:37 w kategorii: pro
Tagi:

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.


Komentarze

dotnetomaniak.pl

23 listopada 2009 02:11

Trackback from dotnetomaniak.pl

Maciej Aniserowicz | Mapowanie Fluent NHibernate i enum

^simon

23 listopada 2009 08:31

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

23 listopada 2009 08:41

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

24 listopada 2009 09:00

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

simon-says-architecture.com

22 kwietnia 2010 05:03

Pingback from simon-says-architecture.com

Oswajanie Fluent NHibernate « Notki Po Polsku « Simon says… architecture!

318.cmanager.org

22 maja 2010 02:22

Pingback from 318.cmanager.org

500sl Headlight Obtuse Mercedes 300sdl, 300sdl Marketing

Komentarze zamknięte