2011-12-30 19 views
6

Provare a creare una soluzione alternativa per l'elaborazione di Enum in Entity Framework utilizzando Generics, ma EF non sembra interessarsi alle proprietà generiche. Ad esempio:Entity Framework: persistente enum in generale?

public enum MyEnum 
{ 
    One, Two, Three 
} 

public class SomePOCOWithEnum 
{ 
     // I want this to persist as an int, but EF doesn't like generics. 
     public EnumWrapper<MyEnum> MyEnumProperty { get; set; } 
} 

L'intenzione è di mantenere l'enum come INT nel database. C'è un modo speciale di usare fluentemente o forse qualche altro metodo di meccanismo con cui posso creare detta classe generica e mantenerla come INT al database all'interno di EF?

L'intenzione è di mantenere le cose generiche come ho circa due dozzine di enumerazioni che hanno bisogno di essere persistenti, e preferisco non scrivere singole classi di wrapper per ognuna di esse.

Ecco la classe generica EnumWrapper, che dimostra quello che mi piacerebbe realizzare: conversione implicita a enum, ma la persistenza come un int:

public class EnumWrapper<T> where T : struct 
{ 
    private T enumValue; 
    public int Value 
    { 
     get { return Convert.ToInt32(enumValue); } 
     set { enumValue = (T)Enum.Parse(typeof(T), value.ToString()); } 
    } 

    public T EnumValue 
    { 
     get { return enumValue; } 
     set { enumValue = value; } 
    } 

    public static implicit operator T(EnumWrapper<T> wt) 
    { 
     return wt.EnumValue; 
    } 

    public static implicit operator EnumWrapper<T>(T t) 
    { 
     return new EnumWrapper<T>() { EnumValue = t }; 
    } 

    public override string ToString() 
    { 
     return enumValue.ToString(); 
    } 
} 
+0

Perché stai avvolgendo le enumerazioni? Sembra terribilmente ingombrante. – phoog

+0

Perché EF non mantiene l'enumerazione. Sono aperto a qualsiasi modo migliore per farlo. –

+2

Enum supportato è stato aggiunto in EF 5, quindi potresti voler [dare un'occhiata] (http://msdn.microsoft.com/en-us/data/hh859576.aspx) – sinelaw

risposta

4

Come sinelaw ha già sottolineato, EF5 ha il supporto esplicito per Enum, ma se non puoi migrare ad esso per qualsiasi motivo, l'approccio che ho preso potrebbe funzionare per te.

Per questo esempio, supponiamo che la tabella sia denominata "Email" e abbiamo una colonna denominata "Priorità". Imposta la colonna come int come faresti normalmente. Successivamente, nel progetto entità, creare una classe enumerazioni che mappa i valori int:

public enum EmailPriorityEnum 
{ 
    Now = 100, 
    Soon = 1000, 
    Whenever = 10000 
} 

Infine, nel progetto entità, creare un file di classe parziale corrispondenti alla entità e mappare manualmente l'enum c'è:

public partial class Email 
{ 
    public EmailEnums.EmailPriorityEnum EmailPriority 
    { 
     get { return (EmailEnums.EmailPriorityEnum)Priority; } 
     set { Priority = (int)value; } 
    } 
} 

Da lì in poi, il codice può fare riferimento a questa proprietà in modo trasparente. Gli svantaggi principali di questo approccio sono:

  1. È necessario fare attenzione che tutti i valori possibili siano mappati nell'enumerazione con gli id ​​appropriati. Per le enumerazioni che cambiano spesso questo diventa problematico.
  2. Gli sviluppatori avranno ancora accesso alla colonna sottostante, a meno che non si modifichi l'accessibilità e sia possibile ignorare l'enumerazione e utilizzare qualsiasi valore desiderato.
+0

Grazie Heather. Sfortunatamente, sto cercando di evitare di scrivere singole proprietà e/o classi wrapper per ogni enum, dato che ne ho circa due dozzine. Fondamentalmente, sto cercando di trovare la soluzione più efficiente che possa essere riutilizzata universalmente, se esiste una soluzione del genere. Una singola classe generica che potrei usare per tutti loro sarebbe l'ideale, ma è lì che sono bloccato. –

+0

Ovviamente, hai ragione che l'aggiornamento a EF5 sarebbe la soluzione più universale, se potessi. :) –