2

I am trying to save an Enum that exists in my model down to the database but everytime I do Entity Framwework complains that there is no look up table associated with the Enum. I do not want a look up table, I just want the enum to exist in code and be stored as integers in the database.

An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.

"Cannot insert the value NULL into column 'Type', table 'Test.dbo.Interests'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated.

The value for Type is definitely not null, EF just treats it that way cause it can't find a Foreign key table that I don't want in the first place.

How do I get entity framework to treat my enum as an int and then convert back out when I call down to the database to retrieve my model?

tereško
  • 58,060
  • 25
  • 98
  • 150
Khalid Abuhakmeh
  • 10,709
  • 10
  • 52
  • 75
  • possible duplicate of [How to work with Enums in Entity Framework?](http://stackoverflow.com/questions/1526339/how-to-work-with-enums-in-entity-framework) – Forgotten Semicolon May 20 '11 at 14:49
  • as some stated this is not a supported feature of EF, please go to http://data.uservoice.com/forums/72027-wcf-data-services-feature-suggestions/suggestions/1012609-support-enums-as-property-types-on-entities?ref=title and vote for that to be included in future releases – Kris Ivanov May 20 '11 at 14:57

4 Answers4

6

Entity framework doesn't support enums at all so you cannot map enum property to the database. You must use int property instead and if you want enum as well you must define another not mapped property (in case of autogenerated entities you must define it in your partial class) which converts int to enum.

Edit: Enum support was added in later version. If you want to map enums (integer values, not strings at the moment) you need to use .NET 4.5 and EF5 or EF6.x and .NET 4.x.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Enums have been discussed as a future release: http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx?CommentPosted=true#commentmessage – Dave Swersky May 20 '11 at 14:56
  • see enum support in latest versions of entity framework. – juFo Mar 20 '14 at 13:10
  • @juFo: Sure, but this is answer from 2011 where enums were not supported. There is another answer in the thread mentioning that enums support was added in .NET 4.5 + EF5. – Ladislav Mrnka Mar 20 '14 at 13:22
  • @LadislavMrnka this post came as the suggested answer in my search results, but it is not relevant anymore. You could adjust the answer to "EF doesn't support enums at all in the older version" or something similar. – juFo Mar 20 '14 at 13:25
2

As of Entity Framework 5, which ships with .NET 4.5, enums are supported as types for properties.

This works for both code first and EF designer scenarios.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
2

I found this way of doing it and it works, it just isn't the Enum directly. You have to create a facade class that can implicitly be mapped back and forth. It works, but not as smooth as I would have liked.

http://daniel.wertheim.se/2010/06/09/dealing-with-enumerations-and-entity-framework-4-code-first/

public enum InterestTypes
{
    [Description("Attraction - for sightseers and adventurers.")] Attraction = 1,
    [Description("Event - fun for everyone (limited time).")] Event = 2,
    [Description("Recreation - parks, hiking, movies...")] Recreation = 3,
    [Description("Restaurant - good eats.")] Restaurant = 4
}

public class InterestType
{
    private InterestType()
        : this(default(InterestTypes))
    {
    }

    public InterestType(int value)
    {
        Value = value;
    }

    public InterestType(InterestTypes type)
    {
        Value = (int) type;
    }

    public int Value { get; private set; }

    public static implicit operator int(InterestType type)
    {
        return type.Value;
    }

    public static implicit operator InterestType(int value)
    {
        return new InterestType(value);
    }

    public static implicit operator InterestTypes(InterestType type)
    {
        return (InterestTypes) type.Value;
    }

    public static implicit operator InterestType(InterestTypes type)
    {
        return new InterestType(type);
    }
}

In your DataContext you need the following in your OnModelCreating method.

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.ComplexType<InterestType>()
            .Property(o => o.Value)
            .HasColumnName("Type");
    }

This tells Entity Framework to map the int value to the value in the database. I guess you could also use strings if you wanted to store the values as strings in the database.

Khalid Abuhakmeh
  • 10,709
  • 10
  • 52
  • 75
0

In my projects I am mapping the enum to an integer column in database, and I restrict access to the property in my POCO model. Something like the example below.

public enum MyEnum
{
    EnumProp1,
    EnumProp2
}

public class MyEntity
{
    public long Id{get;set;}

    [Column("MyEnum")]
    public int IdMyEnum{ get;protected set;}

    [NotMapped]
    public MyEnum
    {
         get{ return (MyEnum)this.IdMyEnum; }
         set{ this.IdMyEnum = (int)value; }
    }
 }

Hope it Helps!

Lelis718
  • 627
  • 7
  • 16