2011-07-27 14 views
17

Sto sperimentando con PetaPoco per convertire una tabella in POCO.PetaPoco gestisce le enumerazioni?

Nel mio tavolo, ho una colonna denominata TheEnum. I valori in questa colonna sono stringhe che rappresentano le seguenti enum:

public enum MyEnum 
{ 
    Fred, 
    Wilma 
} 

PetaPoco soffoca quando tenta di convertire la stringa "Fred" in un valore MyEnum.

Lo fa nel metodo GetConverter, nella linea:

Convert.ChangeType(src, dstType, null); 

Qui, src è "Fred" (un string), ed è dstTypetypeof(MyEnum).

L'eccezione è un InvalidCastException, dicendo Invalid cast from 'System.String' to 'MyEnum'

Mi sto perdendo qualcosa? C'è qualcosa che devo registrare per primo?

io ho tutto il problema aggiungendo la seguente nel metodo GetConverter:

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

Ovviamente, non voglio correre questo delegato ad ogni ferro in quanto sarà rallentare le cose tremendamente. Potrei registrare questo enum e i suoi valori in un dizionario per velocizzare le cose, ma mi sembra che qualcosa del genere sia già nel prodotto.

Quindi, la mia domanda è: devo fare qualcosa di speciale per registrare la mia enumerazione con PetaPoco?

aggiornamento 23 Febbraio 2012

ho submitted a patch qualche tempo fa, ma non è stato tirato in ancora. Se vuoi usarlo, guarda la patch ed entra nel tuo codice, oppure prendi il codice from here.

+0

** Aggiornamento 28 giu 2012 ** la patch esatta non è stata ancora applicata ma è stato aggiunto un codice simile nel [ramo v5] (https://github.com/toptensoftware/PetaPoco/tree/v5). Vedi anche http://www.toptensoftware.com/Articles/137/Long-Time-No-Post-and-PetaPoco-v5 –

+0

Se non è difficile per te, pls invia patch anche a npoco. Ti consiglio di passare a npoco, perché ha uno sviluppo più attivo e ha tutte le funzionalità di PetaPoco e anche di più. – AuthorProxy

+0

** Aggiornamento 9 settembre 2014 ** La risposta @iano è quella corretta per la versione ** 5.0.2 ** più recente. –

risposta

5

Hai ragione, la gestione delle enumerazioni non è integrata in PetaPoco e di solito suggerisco di fare esattamente ciò che hai fatto.

Si noti che questo non rallenterà le cose per le richieste che non usano il tipo di enum. PetaPoco genera codice per mappare le risposte ai pocos in modo che il delegato venga chiamato solo quando realmente necessario. In altre parole, GetConverter verrà chiamato solo la prima volta che viene utilizzato un particolare tipo poco, e il delegato verrà chiamato solo quando un enumerato richiede una conversione. Non sei sicuro della velocità di Enum.Parse, ma sì puoi memorizzare la cache in un dizionario se è troppo lento.

+0

Grazie Brad. Aggiungerò le ricerche enum e invierò una patch. –

+0

Come da Dec 27, 2011 la patch non è stata applicata. Sarà una bella aggiunta. – JCallico

+0

** Aggiornamento 28 giugno 2012 ** la patch esatta non è stata ancora applicata ma è stato aggiunto un codice simile nel [ramo v5] (https://github.com/toptensoftware/PetaPoco/tree/v5). Vedi anche http://www.toptensoftware.com/Articles/137/Long-Time-No-Post-and-PetaPoco-v5 –

5

Sto usando 4.0.3 e PetaPoco converte automaticamente enumerazioni in numeri interi e viceversa. Tuttavia, volevo convertire le mie enumerazioni in stringhe e viceversa. Approfittando di Steve Dunn's EnumMapper e di PetaPoco IMapper, mi sono inventato questo. Grazie ragazzi.

Si noti che non gestisce Nullable<TEnum> o valori nulli nel DB. Per usarlo, impostare 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

Se si utilizza la generazione di T4 PetaPoco e desideri enumerazioni nel vostro tipo generato, è possibile utilizzare l'override PropertyType nel database.TT:

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

Molto utile. Grazie! –

0

ti voglio per memorizzare il valore della enum invece del numero di indice (1,2,4 per esempio) è possibile individuare la funzione di aggiornamento in classe PetaPoco perché il codice è "gestito", ecc , quando lo aggiungi come pacchetto nuget, il file .cs verrà archiviato nel tuo progetto. Se avremmo la variabile enum Colore = {rosso, giallo, blu}

Invece di:

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

modifica:

//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); 
} 

Sarebbe memorizzare "giallo" invece di 2

Problemi correlati