locked
Mapping a field to an enum property RRS feed

  • Question

  • Does somebody have an example that show how to map an enum property to a database field with the entity framework? I'am having a real hard time trying to figure this one out.

     

    Thanks

    Monday, September 17, 2007 3:25 PM

Answers

  • Unfortunately, this isn't something we support directly in the entity framework in this release. 

     

    Part of the reason for that is that there are a number of non-obvious subtleties in how this should work.  For example, let's say that you have an enum in your CLR code which has 3 possible values (red, green, blue), and you want to map this to some column in the database.  Do you hard-code the mapping in your MSL such that red = 1, green = 2, blue = 3?  If so, how do you restrict the database column to only have those three values, and if someone puts another value in that column, what should your enum value in the CLR be (or should an exception just be thrown)? 

     

    Another possibility that many folks consider at first is that they actually want to have a reference table in their database which maps between the enum values and some ID so that you have a table which has one column that is the integer and another column that is a string representing the enum value.  In this case the mapping gets even more complicated.

     

    There are solutions to many of these problems, but they can get involved, and in the end this feature was postponed to a future release.

     

    - Danny

     

    Monday, September 17, 2007 3:35 PM

All replies

  • Unfortunately, this isn't something we support directly in the entity framework in this release. 

     

    Part of the reason for that is that there are a number of non-obvious subtleties in how this should work.  For example, let's say that you have an enum in your CLR code which has 3 possible values (red, green, blue), and you want to map this to some column in the database.  Do you hard-code the mapping in your MSL such that red = 1, green = 2, blue = 3?  If so, how do you restrict the database column to only have those three values, and if someone puts another value in that column, what should your enum value in the CLR be (or should an exception just be thrown)? 

     

    Another possibility that many folks consider at first is that they actually want to have a reference table in their database which maps between the enum values and some ID so that you have a table which has one column that is the integer and another column that is a string representing the enum value.  In this case the mapping gets even more complicated.

     

    There are solutions to many of these problems, but they can get involved, and in the end this feature was postponed to a future release.

     

    - Danny

     

    Monday, September 17, 2007 3:35 PM
  • Enum properties are not currently supported by the Entity Framework. As a workaround, consider mapping to a property with the underlying value type (normally System.Int32) and casting to and from the enum type in your application (or for convenience, you can define a new property on the entity type as shown).

     

    Code Snippet

            [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]

            public int EntityProperty

            {

                get { … }

                set { … }

            }

     

            public MyEnum ApplicationProperty

            {

                get { return (MyEnum)this. EntityProperty; }

                set { this. EntityProperty = (int)value; }

            }

     

     

    Thanks,

    -Colin

    Monday, September 17, 2007 4:05 PM
  • Thanks Colin, that is what I am doing already, excet that the generated property is private. I think it's  a very weak point for the enity framework not to support this kind of pattern. I do not need fancy validations of restricted values in database. I only need to map an enum to a integer field, for the purpose of clarity in my code.

    Monday, September 17, 2007 5:04 PM
  • Am I understanding this correctly...the first release of EF will not support mapping to properties that are enumerations? Every other OR solution handles this problem. I don't discount the complexities involved, but you have to admit that you need support for the most common scenario (mapping an Int32 to a Enum, if it doesn't match, throw an exception) in the first release. Have the previous 4+ years (all the way back to ObjectSpaces) been a waste? Enumerations are very much integral to the object world. (no pun intended). Without support for them, we are still left with artifacts from the relational world...the impedence mismatch is still there.

     

    Think of it this way. Without support for enumerations, my LINQ query either isn't possible (becuase you cannot use non-EF mapped properties in a LINQ query, as shown the previous post example code) or my query looks like this (not natural):

     

    Code Block

    var orders = from o in entities.Order

    where o.Status == (int)OrderStatus.Open

    select o

     

    foreach (var order in orders)

    {

    Console.WriteLine("{0}", (OrderStatus)order.Status);

    }

     

    If the enum was supported, I would not need the casting and I would have intellisense all the way to aid in the development. Then, my code would be pretty :-)

     

    Code Block

    var orders = select o from entities.Order

    where o.Status == OrderStatus.Open

    select o

     

     

    I really hope scenario is support before EF reaches RTM. Otherwise, developers will certainly feel short changed and complain about the loss of an important language capability.

     
    Thursday, December 13, 2007 1:49 AM
  • I appreciate your feedback and the importance of this feature.  On the other hand, there are a few important realities here:

    • The list of features like this which are very important is quite long (and how things should be prioritized is definitely different according to different people.
    • There's no way we can address all of the needs in v1.  As painful as it is now, the truth is that it's much better for all of us that we draw the line somewhere soon and ship.  A critical transformation for the better happens to a product when it ships.
    • The EF is only one part of a broad-based effort to create a complete data platform.  The scope of that overall vision is something which we probably haven't been as clear about as we should.  Sometimes the trade-offs we make with regard to feature prioritization don't really make sense without that context.  If our goal was just to build an OR solution, then this and other things might make the cut sooner.  Given that we are trying to define the components that will enable us to extend entity services in a coordinated way not only to objects but also to reporting, replication, analysis services, sharepoint, CRM, web services, work flow and many more things over time, we end up sometimes having to focus on other priorities.

    I know that this doesn't help address the particular pain point you are facing right now, and we try hard to temper the big vision, strategic stuff with work to address immediate requests and pain points.  I just have to set expectations that this won't make v1, and we hope you can hang with us as we address some things in v1 and work to address many more in v2 and beyond.

     

    - Danny

    Thursday, December 13, 2007 5:50 AM
  • Thanks for the reply. As a former developer on the TFS product team, I completely understand how important it is to ship a product. I also have a good idea about the direction of Microsoft's data access strategy (and I love it!). My concern is that from a consumer perspective, this seems like a big weak spot in the first offering. Something like this could have a significant impact on the adoption of the technology. Most development shops are not advanced enough to see the big picture here. They will most likely just think of EF as yet another object-relational mapper. If that's the case (and I argue that it is), adoption will be negatively affected by this weak point.

     

    With a v1 product like this, I find it hard to believe that you will create a huge paradigm shift in the eyes of most developers. That kind of shift takes time, and it takes longer than one release. With that in mind, I'd argue that getting developers to invest in this platform is important. Why would developer's invest in a platform that doesn't even support simple enumerations? That's the question they will ask. Remember, they're just thinking of EF as another O/R offering.

     

    As the platform grows, the big paradigm shift will eventually happen for everyone and they'll see the great value this platform provides. But if they never invested in the first place, they cannot benefit from the platform and cannot provide valuable feedback to you.

     

    Isn't the adoption of this platform already in question, given its troubled past (ObjectSpaces, WinFS, etc.)? Making developers wait for v2 for simple enumeration support seems risky. How long will v2 take? 5 more years? The development community has waited a long time for this product offering. Delay after delay... Now we are being told that even something as seemingly simple as enumerations is not supported. That makes the framework appear weak. Whether that's true or not really isn't important. Most developers will see it as weak and use another offering/solution.

     

    I know I am not the only one to complain about enumerations. In fact, I'd bet that a lot of folks don't like this cut. Please remember that shipping is important, but shipping the right product is even more important.

     

    Something to think about.

     

    Thursday, December 13, 2007 1:18 PM
  • > Part of the reason for that is that there are a number of non-obvious subtleties in how this should work.  For example, let's say that you have an enum in your CLR code which has 3 possible values (red, green, blue), and you want to map this to some column in the database.  Do you hard-code the mapping in your MSL such that red = 1, green = 2, blue = 3?  If so, how do you restrict the database column to only have those three values, and if someone puts another value in that column, what should your enum value in the CLR be (or should an exception just be thrown)? 

     

    Honesty, that is a lame reason.

     

    I fully understand that many database administrators require that the database should be self-validating and prevent all bogus input (I.e. validate red=1, green=2, blue=3, 4=exception). However, many other developers support multiple database backends and believe that the middle-tier should validate data and transactions, not the database.

     

    I expect this:

     

    THE ENTITY FRAMEWORK SHOULD SUPPORT A SIMPLE ENUMERATION.

     

    This is such an easy task to resolve that I really don't get it. A simple type converter from enum to integer is all that is needed.

     

    As for the supplied argument -  validation, the obvious answer is that the Enity Framework uses a database as the source for its code gnerator, it does not modify the datbase anyway... but... it does support stored procedures So, if any particular db admin wants enum values validated within the database they can include a stored procedure - nothing stops them. On the other hand, other users that believe the middle-tier is the appropriate place for validation would also be supported.

     

    >> Another possibility that many folks consider at first is that they actually want to have a reference table in their database which maps between the enum values and some ID so that you have a table which has one column that is the integer and another column that is a string representing the enum value.  In this case the mapping gets even more complicated.

     

    This is an irrelevant point - in this case it is no longer a simple enumeration. The "enum type" is a database table and this is already supported by the Entity Framework. It would be absolutely and monumentally dumb to have a database table where end-users could modify the list (enumeration) values and also have a hardcoded (literal) enumeration that could not be modified by end-users. Thus, any changes would crash the system. The whole point of using a table is to allow for end-user changes as well as have what the enum values represent stored within the database.

     

     

     

    Thursday, December 13, 2007 4:38 PM
  •  John Morris (SPRO) wrote:

    adoption will be negatively affected by this weak point.



    I whole-heartily agree. I can understand the reluctance to put this in v1 because they want to do it right, but I think it will be a hard sell to get my group to change our object design guidelines (we use enums for things like statuses quite a bit).
    Thursday, December 13, 2007 6:45 PM
  •  

    I would also like to add my vote for adding enum support.

     

    Even LINQ to SQL supports this!

    Tuesday, January 1, 2008 5:01 PM
  •  

    I'm also voting for simple enum supprot in first release.

    Most common scenario is int<->enum mapping.

    "dictionary-like" enums could be added later

     

    wojciech gebczyk

     

    Thursday, January 3, 2008 10:21 AM
  • So by this discussion I presume that more complex conversion ( ie taking a string in a database and convert it into a instance of a complex type) would also be out of the question.

     

    this being true I would agree that these are basic functions of any decent ORM and almost a must for any type of Domain / Model driven development. It really diminishes the possibility of adoption until such functionality is available.

     

    Definitely add my vote for type conversion functionality

    Friday, January 18, 2008 10:24 AM
  • +1 on needing Enums.

     

    Even Linq to SQL supports it. (although the designer doesn't really).

     

    Just let us type in a fullly qualified .NET enum name for now in the type field. You already know it's int32 (or tinyint) so just go nuts with that and we're set.

     

    And yes, throw an error if you get a bogus value, but only when the property is accessed. Don't blow up the entire object just because it's bogus.

     

    This will be used EVERY TIME THERE IS INHERITENCE with a Type descriptor field, so it's a MUST.

    Friday, May 9, 2008 5:40 PM
  •  

    +1
    Friday, May 23, 2008 6:49 AM
  • I can understand that there has to be a feature cut off point somewhere, and that some advanced features have to be delayed until later versions, but surely enum support falls under the basic and fundamental category.

     

    The feedback from people on this is clear - lack of suport in v1 is obviously going to be a real pain point, especially considering other ORMs support it.

    Friday, May 23, 2008 9:23 AM
  • So, these posts are two years old, are enum's supported yet?
    Saturday, May 8, 2010 9:32 AM
  • From this page

    http://blogs.msdn.com/b/efdesign/archive/2011/06/29/enumeration-support-in-entity-framework.aspx

    "in which enums currently has more than 1,600 votes. That is about 50% more votes than Code First!"

    They say it is by far the most popular feature request and say it is complicated to add yet they have gone and implemented rubbish features like code first (which surely must have been MUCH more complicated) while ignoring fundamental features like enum support, undo, clone etc.

    Wednesday, July 11, 2012 11:19 PM