Localized enums with Entity Framework Code-First 4.1 in WPF MVVM and ASP.NET MVC 3

By Mirek on (tags: ASP.NET MVC, Code First, Entity Framework, enums, localization, mvvm, WPF, categories: code, web)

In part 1) I would like to present the solution of using enum types with Entity Framework Code-First (EF CF later). Then in part 2) I would like to show how easily display these enums in WPF MVVM and in Part 3)  I will try to explain my approach for displaying and binding localized enums in ASP.NET MVC 3 application.

EF CF approach is still developed and in version 4.1 it does not support mapping enum typed properties to database (Entity Framework June 2011 CTP already does!) . You can find a few workarounds for that on the web. For instance Daniel Wertheim’s proposal using complex type enum mapper which you can find here. Each solution has its pros and cons, and I would like to present one, which is in my opinion easiest (in sense of coding effort) and most extensible.

I will try to put here the key chunks of code assuming that the reader has basic knowledge about used technologies and tools.

Part 1. Mapping enum in Entity Framework Code-First

The enum type looks as follows

   1: public enum Status
   2: {
   3:     Online,
   4:     Busy,
   5:     Away,
   6:     Offline
   7: }

and is mapped to the property named Status in following POCO class

   1: public class Client
   2: {
   3:     public int Id { get; set; }
   4:  
   5:     public string Name { get; set; }
   6:  
   7:     [Column("Status")]
   8:     public int statusValue { get; protected set; }
   9:  
  10:     [NotMapped]
  11:     public Status Status
  12:     {
  13:         get
  14:         {
  15:             return (Status)statusValue;
  16:         }
  17:         set
  18:         {
  19:             statusValue = (int)value;
  20:         }
  21:     }
  22: }

The trick here relay on property Status and its backing field(property) statusValue. Status has public getter and setter and is accessible outside the class. Is marked with NotMapped attribute which indicates that EF CF will ignore it during building the model so it will not be mapped to the table column. At the other hand field/property statusValue will be considered by EF CF, and will be mapped to a column with name Status as described by Column attribute. This is because we want to have a Status column in the table and a Status property in POCO. Moreover when EF CF will support mapping enums in future we won't need to change the column name in database. The only required change will consist of removing statusValue property and changing Status property to something like this:

   1: public Status Status { get; set; }

One more thing to consider is the type of the statusValue property. Every enumeration type has an underlying type, which can be any integral type except char. The default underlying type of the enumeration elements is int. By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1.

The statusValue property is public because of EF CF requirements. It could has protected modifier to not be visible outside the class, but then would not be mapped to the database. Instead the only workaround is making its setter protected, which is allowed in EF CF and prevent setting incorrect int values to it from outside the class. So this is the only disadvantage of this solution that statusValue is visible outside the class.