2011-07-27 15 views
17

Eksperymentuję z PetaPoco, aby przekształcić tabelę w POCO.Czy PetaPoco obsługuje wyliczenia?

W moim stole mam kolumnę o nazwie TheEnum. Wartości w tej kolumnie są ciągi, które reprezentują następujące wyliczenia:

public enum MyEnum 
{ 
    Fred, 
    Wilma 
} 

PetaPoco dławi gdy próbuje przekonwertować ciąg „Fred” na wartość MyEnum.

Czyni to w sposób GetConverter, w linii:

Convert.ChangeType(src, dstType, null); 

Tutaj src jest "Fred" (a string) i dstType jest typeof(MyEnum).

Wyjątkiem jest InvalidCastException mówiąc Invalid cast from 'System.String' to 'MyEnum'

Am I czegoś brakuje? Czy jest coś, co muszę najpierw zarejestrować?

mam sobie z tym problemem poprzez dodanie następujących do metody GetConverter:

if (dstType.IsEnum && srcType == typeof(string)) 
{ 
    converter = delegate(object src) 
      { 
       return Enum.Parse(dstType, (string)src) ; 
      } ; 
} 

Oczywiście, nie chcę, aby uruchomić ten delegata na każdym rzędzie jak będzie to spowolnić ogromnie. Mogłabym zarejestrować to wyliczenie i jego wartości w słowniku, aby przyspieszyć działanie, ale wydaje mi się, że coś podobnego prawdopodobnie już byłoby w produkcie.

Moje pytanie brzmi, czy muszę zrobić coś specjalnego, aby zarejestrować moje wyliczenia z PetaPoco?

Aktualizacja 23 lutego 2012

submitted a patch ja jakiś czas temu, ale nie została jeszcze wciągnięta. Jeśli chcesz go użyć, spójrz na poprawkę i połącz się z własnym kodem lub uzyskaj kod: from here.

+0

** Aktualizacja 28 czerwca 2012 ** dokładna łatka nie została jeszcze zastosowana, ale dodano podobny kod w gałęzi [v5] (https://github.com/toptensoftware/PetaPoco/tree/v5). Zobacz także http://www.toptensoftware.com/Articles/137/Long-Time-No-Post-and-PetaPoco-v5 –

+0

Jeśli nie jest to dla ciebie trudne, pls przesyłaj łatkę również na npoco. Polecam przełączyć na npoco, ponieważ ma bardziej aktywny rozwój i posiada wszystkie funkcje, które ma PetaPoco, a nawet więcej. – AuthorProxy

+0

** Aktualizacja 9 września 2014 ** Odpowiedź @iano jest poprawna dla najnowszej wersji ** 5.0.2 **. –

Odpowiedz

5

Masz rację, obsługa wyliczeń nie jest wbudowana w PetaPoco i zwykle po prostu sugeruję robić dokładnie to, co zrobiłeś.

Należy zauważyć, że nie spowoduje to spowolnienia procesu dla wniosków, które nie używają typu wyliczeniowego. PetaPoco generuje kod do odwzorowania odpowiedzi na pocos, więc delegat zostanie wywołany tylko wtedy, gdy jest naprawdę potrzebny. Innymi słowy, GetConverter zostanie wywołany tylko wtedy, gdy użyty zostanie określony rodzaj poco, a delegat zostanie wywołany tylko wtedy, gdy enum wymaga konwersji. Nie jestem pewny szybkości programu Enum.Parse, ale tak, możesz przechowywać w pamięci podręcznej, jeśli jest zbyt wolny.

+0

Dzięki Brad. Dodam wyliczenia enum i prześlę łatkę. –

+0

Na dzień 27 grudnia 2011 łatka nie została zastosowana. Będzie miłym dodatkiem. – JCallico

+0

** Aktualizacja 28 czerwca 2012 ** dokładna łatka nie została jeszcze zastosowana, ale podobny kod został dodany w gałęzi [v5] (https://github.com/toptensoftware/PetaPoco/tree/v5). Zobacz także http://www.toptensoftware.com/Articles/137/Long-Time-No-Post-and-PetaPoco-v5 –

5

Używam 4.0.3, a PetaPoco automatycznie konwertuje enum na liczby całkowite iz powrotem. Jednak chciałem przekonwertować moje wyrazy na ciągi iz powrotem. Korzystając z Steve Dunn's EnumMapper i IMapper PetaPoco, wymyśliłem to. Dzięki chłopaki.

Należy zauważyć, że nie obsługuje on wartości Nullable<TEnum> lub wartości pustych w DB. Aby z niego skorzystać, należy ustawić PetaPoco.Database.Mapper = new MyMapper();

class MyMapper : PetaPoco.IMapper 
{ 
    static EnumMapper enumMapper = new EnumMapper(); 

    public void GetTableInfo(Type t, PetaPoco.TableInfo ti) 
    { 
     // pass-through implementation 
    } 

    public bool MapPropertyToColumn(System.Reflection.PropertyInfo pi, ref string columnName, ref bool resultColumn) 
    { 
     // pass-through implementation 
     return true; 
    } 

    public Func<object, object> GetFromDbConverter(System.Reflection.PropertyInfo pi, Type SourceType) 
    { 
     if (pi.PropertyType.IsEnum) 
     { 
      return dbObj => 
      { 
       string dbString = dbObj.ToString(); 
       return enumMapper.EnumFromString(pi.PropertyType, dbString); 
      }; 
     } 

     return null; 
    } 

    public Func<object, object> GetToDbConverter(Type SourceType) 
    { 
     if (SourceType.IsEnum) 
     { 
      return enumVal => 
      { 
       string enumString = enumMapper.StringFromEnum(enumVal); 
       return enumString; 
      }; 
     } 

     return null; 
    } 
} 
5

Jeśli używasz generacji T4 PetaPoco i chcesz teksty stałe w swojej generowanego typu, można użyć nadpisanie PropertyType w bazie danych.TT:

tables["App"]["Type"].PropertyType = "Full.Namespace.To.AppType"; 
+0

Bardzo pomocne. Dzięki! –

0

I chcesz zapisać wartość enum zamiast numeru indeksu (1,2,4 na przykład) można zlokalizować funkcji aktualizacji w klasie PetaPoco ponieważ kod jest „udało” etc , po dodaniu go jako pakietu nuget zapisze plik CS na swoim projekcie. Jeśli mielibyśmy zmiennej enum color = {czerwony, żółty, niebieski}

Zamiast:

// Store the parameter in the command 
AddParam(cmd, pc.GetValue(poco), pc.PropertyInfo); 

zmiana:

//enum? 
if (i.Value.PropertyInfo.PropertyType.IsEnum) 
{ 
     AddParam(cmd, i.Value.GetValue(poco).ToString(), i.Value.PropertyInfo); 
} 
else 
{ 
     // Store the parameter in the command 
     AddParam(cmd, i.Value.GetValue(poco), i.Value.PropertyInfo); 
} 

To będzie przechowywać "żółty" zamiast 2