Fluent NHibernate map Enum as Lookup Table

Mam następujące (uproszczone)

public enum Level
{
    Bronze,
    Silver,
    Gold
}

public class Member
{
    public virtual Level MembershipLevel { get; set; }
}

public class MemberMap : ClassMap<Member>
{
    Map(x => x.MembershipLevel);
}

Tworzy tabelę z kolumną o nazwie MembershipLevel z wartością jako wartością ciągu Enum.

Chcę, aby cały Enum został utworzony jako tabela wyszukiwania, a tabela Członkowska odwołuje się do tego z wartością całkowitą jako FK.

Chcę to zrobić bez zmiany mojego modelu.
Author: Lachlan Roche, 2010-04-03

2 answers

Aby odwzorować właściwość enum jako kolumnę int, użyj metody CustomType.

public class MemberMap : ClassMap<Member>
{
    Map( x => x.MembershipLevel ).CustomType<int>();
}

Aby zsynchronizować tabelę enum i lookup, dodałbym tabelę lookup i dane do Twoich skryptów sql. Test integracji może sprawdzić, czy wartości tabeli enum i lookup są takie same.

Jeśli chcesz, aby SchemaExport stworzył tę tabelę, Dodaj klasę i odwzoruj dla niej.

public class MembershipLevel
{
    public virtual int Id { get; set; }
    public virtual string Code { get; set; }
}

public class MembershipLevelMap : ClassMap<MembershipLevel>
{
    Id( x => x.Id );
    Map( x => x.Code );
}

Jeśli tworzysz tabelę z SchemaExport, musisz ją również wypełnić:

foreach (Level l in Enum.GetValues( typeof( Level ))) {
    session.Save( new MembershipLevel{ Id = (int) l, Code = l.ToString() });
}
 20
Author: Lachlan Roche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-07 01:34:14

Nie zrobiłbym tego, ponieważ twoja deklaracja Enum nie jest dynamiczna lub prostsza, nie zmienia się bez rekompilacji, podczas gdy twoja tabela wyszukiwania może się zmienić w dowolnym momencie. Jeśli wartości tabeli Enum i lookup nie pasują, co dalej?

Innym powodem jest to, że jeśli zmienisz Enum (w kodzie), będziesz musiał zsynchronizować je z tabelą bazy danych. Ponieważ liczby nie mają klucza przyrostowego( PK), nie można ich tak łatwo zsynchronizować. Załóżmy, że usuniesz jednego członka Enum ze swojego kodu i przekompiluj to, co ma się stać? A jeśli zmienisz wartość?

Mam nadzieję, że wyraziłem swoje zastrzeżenia wobec tego podejścia jasno. Dlatego zdecydowanie zalecam przechowywanie nazwy lub wartości członków enum. Aby zapisać go po nazwie, po prostu Mapuj tak:

public class MemberMap : ClassMap<Member>
{
    Map(x => x.MembershipLevel, "level")
        .CustomType<GenericEnumMapper<Level>>()
        .Not.Nullable();
}

Aby zapisać wartości, zrób tak, jak napisał @ Lachlan w swojej odpowiedzi.

Lub jeśli naprawdę potrzebujesz tabeli wyszukiwania i chcesz użyć Enum ze ścisłym sprawdzaniem, Utwórz normalny model z PK (lub użyj wartości do tego), Klucz i wartość. Utwórz swoje enum ze statycznymi członkami i spraw, aby aplikacja zapytała bazę danych o nazwy i wartości po jej uruchomieniu. Jeśli coś się nie zgadza, rób co chcesz. Dodatkowo, nie gwarantuje to, że tabela nie zmieni się podczas działania programu, więc lepiej upewnij się, że tak nie jest.

 5
Author: jweyrich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-09 04:58:22