53

What is the best way to work with Enums in Entity Framework?

Remarks: I'm using EF 3 and Firebird.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
Rafael Romão
  • 1,788
  • 3
  • 20
  • 35
  • [This works too](http://daniel.wertheim.se/2010/06/09/dealing-with-enumerations-and-entity-framework-4-code-first/) – Korayem Jul 01 '11 at 20:29

5 Answers5

27

There is a somewhat better way to do it in EF 4. Unfortunately, it won't work in EF 1.

Here's another approach.

Update: Real enum support was added in the June 2011 EF CTP.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Craig Stuntz
  • 125,891
  • 12
  • 252
  • 273
20

Update:
Entity Framework now supports Enums nativity.

Original:
This is one of those irritating things about EF. Will not be supporting it yet!

Or you can do something like:

public MyEnum MyEnumProperty  
{  
  get { return (MyEnum) InnerEnumProperty; }  
  set { InnerEnumProperty = (int) value; }  
}

But it makes me feel dirty.

Geoff
  • 4,676
  • 3
  • 26
  • 38
  • 2
    its kinda dirty, but there is another problem, if you use this field inside a query, EF will complain. For that problem I created this wrapper: http://landman-code.blogspot.com/2010/08/adding-support-for-enum-properties-on.html which from the outside of your entity allows you to remain clean of EF details.. – Davy Landman Aug 29 '10 at 08:18
11

This question is a bit old, but let me point you to a more recent material since today we have a newer version of Entity Framework:

Video: Entity Framework 5 Enums and Moving Solution from EF 4.3 by Julie Lerman

I used this video today to catch up with enums in Entity Framework. It's a great step by step demonstration. Hope it helps you too.

There's also this introductory post on Entity Framework Design blog:

Enumeration Support in Entity Framework

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
6

I make heavy use of tables (with default values) in DB of the form

CREATE TABLE [dbo].[CommunicationPreferences]
(
    [ID] smallint NOT NULL,
    [SystemName] nvarchar(50) NOT NULL,
    [Description] nvarchar(200) NOT NULL,
)

And I drive my EF4 entities from the DB.

N.B. I use no views, SPROCS or SQL functions, no complex EF types, just direct table to entity mapping. Then extend my entity partial classes to add additional functionality to keep things DRY.

For Enums I have a simple T4 template, which I hand a list of tables (of the form above), the .tt file gets fired off whenever I update the EF model from the DB (or if I need to on demand), it grabs the data, and builds Enums e.g.

/// <summary> 
/// Enums For The dbo Schema
/// </summary>
public enum CommunicationPreferencesList : short
{
    /// <summary> 
    /// HTML Emails
    /// </summary>
    [EnumTextValue(@"HTML Emails")]
    HTMLEmail = 1,

    /// <summary> 
    /// Plain Text Emails
    /// </summary>
    [EnumTextValue(@"Plain Text Emails")]
    PlainEmail = 2,

    /// <summary> 
    /// Mobile Telephone
    /// </summary>
    [EnumTextValue(@"Mobile Telephone")]
    Mobile = 3,

    /// <summary> 
    /// Landline Telephone
    /// </summary>
    [EnumTextValue(@"Landline Telephone")]
    Landline = 4,

    /// <summary> 
    /// SMS
    /// </summary>
    [EnumTextValue(@"SMS")]
    SMS = 5,

}

Then when I am dealing with an FK ID column / Property on some entity e.g.

Users.CommunicationPreferenceID

I simply cast either the ID or the enum for the comparison. e.g.

CommunicationPreferencesList usersPreference = (CommunicationPreferencesList)currentUser.CommunicationPreferenceID;

if(usersPreference == CommunicationPreferencesList.SMS)
{
//send SMS
}
else if(usersPreference == CommunicationPreferencesList.Mobile)
{
//ring the phone
}

I then have some simple helpers to e.g. give the EnumTextValue from an enum instance e.g.

string chosenMethod = EntityHelper.GetEnumTextValue(CommunicationPreferencesList.Mobile);

 => "Mobile Telephone"

I find this simple, hassle free, transparent, easy to use, and for my purposes it works a treat and I am happy. I don't see the need to totally mask the numeric value in the DB / entity from the consuming code, I am quite happy to cast one or other of the values, and end up with pretty clean readable code, plus the nice little extra of the EnumTextValue which is generated from the [Description] field in the DB.

MemeDeveloper
  • 6,457
  • 2
  • 42
  • 58
  • 2
    Interesting idea. There are potential data-integrity issues though. If you delete/edit an existing db entry & regenerate the T4 template, then code using the deleted enum will not compile. And (worse) if someone accidentally deleted a db entry, then re-instated it, the key might be different. Then any enum values saved to database would be associated with the wrong item in the enum (or there wouldn't be a matching value at all). Perhaps doing it the other way round - persisting the enum to db might be less error-prone? – Appetere Mar 01 '13 at 09:16
  • Well maybe but personally have never had any issues... 1. I don't use identity on the PK col, so mismatch with auto incrementing IDs just not possible 2. It doesn't make a difference which way the persistence is going what matters is that someone doesn't change one without the other, or that there's a mechanism to ensure they are kept in synch i.e. I use an automatic default values sql script to set the lookup table data (if its somehow changed) on every app / DB publish 4. we would WANT the code using the deleted entry to not compile. That's the whole point ! – MemeDeveloper Nov 18 '13 at 16:33
0

I had a similar problem and solved it by writing an extension on the entity through the partial class mechanism. I just added a property that does the casting of DB field already in the entity, in our case just an integer.

Only pitfall is to add an ignore serialization attribute, for example when using in combination with WCF.