Up Model

Use Enum types

Last modified on May 21, 2014 09:44

As of version 7.0.3 DevForce 2012 supports Entity Framework enum types.



Overview

A few things to note about enum types:

  • Enum support was introduced in Entity Framework 5 for projects targeting .NET Framework 4.5.
  • An enumeration can have the following underlying types:  Byte, Int16, Int32, Int64 or SByte.
  • Enum types may be used in both Code First and EDMX-based model or database first models. 
  • Enum types may be external to your model, for example System.DayOfWeek, or defined within the model.
  • In DevForce, enum types may be used in all application types and do not require special markup for serialization support.

Enums in Code First models

Let's use a simple example, based on the EF documentation.  

First we'll define an enum type, DepartmentNames:

C#
public enum DepartmentNames : short {
  English = 1,
  Math,
  Economics
}

Next, an entity class using this enum:

C#
[ProvideEntityAspect]
public partial class Department {
 public int DepartmentID { get; set; }
 public DepartmentNames Name { get; set; }
 public decimal Budget { get; set; }
}

Our EntityManager looks like this:

C#
public class EnumTestEntityManager : EntityManager {

 public EntityQuery<Department> Departments { get; set; }
}

Now we can query and save these Department entities as we normally would.  

For example, to create and save entities:

C#
var mgr = new EnumTestEntityManager();
mgr.AddEntity(new Department { Name = DepartmentNames.Economics });
mgr.AddEntity(new Department { Name = DepartmentNames.English });
mgr.SaveChanges();

And to query:

C#
var mgr = new EnumTestEntityManager();
var department = (from d in mgr.Departments where d.Name == DepartmentNames.English select d).FirstOrDefault();
Console.WriteLine("DepartmentID: {0} Name: {1}", department.DepartmentID, department.Name);

Now let's extend the model above to use an existing enum type.  

We'll add a new property MeetingDay to the Department entity: 

C#
[ProvideEntityAspect]
public partial class Department {
 public int DepartmentID { get; set; }
 public DepartmentNames Name { get; set; }
 public System.DayOfWeek MeetingDay { get; set; }
 public decimal Budget { get; set; }
}

System.DayOfWeek is an existing enum type.  You can use any non-system enum types known to your application too. 

We can now query and save these entities as before:

C#
var mgr = new EnumTestEntityManager();
mgr.AddEntity(new Department { Name = DepartmentNames.Math, MeetingDay = DayOfWeek.Wednesday });
mgr.SaveChanges();

var depts = mgr.Departments.Where(d => d.MeetingDay == DayOfWeek.Wednesday).ToList();

Enums in EDMX-based models

Our trusty NorthwindIB database doesn't contain any integer columns which are good candidates for an enum type, so let's continue with the Department entity we saw above.  This sample is also based on the EF documentation.

enum1.JPG

You can add an enum type to your model in two ways, either by "converting" an entity property, or by adding a new enum type in the Model Browser.

Let's convert the Name property in our entity to an enum.  Right click and choose "Convert to Enum" to bring up the "Add Enum Type" dialog.  

We'll call this DepartmentNames and use the same members as in the Code First example above:

enum2.JPG

The designer has now created the new enum type, and converted this property type to the new enum type:

enum3.JPG

When the code is generated, we now see this enum type in the *.IB.Designer file:

C#
#region DepartmentNames enum
public enum DepartmentNames : short {
  English = 0,
  Math = 1,
  Economics = 2,
}
#endregion DepartmentNames enum
VB
#Region "DepartmentNames enum"
Public Enum DepartmentNames As Short
    English = 0
    Math = 1
    Economics = 2
End Enum
#End Region

Uh oh.  Notice the member values differ from what we first defined in the Code First model above.  As with any enum in C# or VB, the first value is 0 if not specified.  You can select the enum type in the Model Browser to edit the member values.

We can now query and save these entities:

C#
var mgr = new EnumTestEntities();
mgr.AddEntity(new Department { Name = DepartmentNames.Economics });
mgr.AddEntity(new Department { Name = DepartmentNames.English });
mgr.SaveChanges();

var department = (from d in mgr.Departments where d.Name == DepartmentNames.English select d).FirstOrDefault();
Console.WriteLine("DepartmentID: {0} Name: {1}", department.DepartmentID, department.Name);

Let's also convert the MeetingDay property to an enum type.  Here we want to use an existing enum type, System.DayOfWeek.  Open the Add Enum Type dialog again:

enum4.JPG

Be sure to check "Reference external types" and supply the full type name of the external enum type.  Also don't supply any member values, as the values will come from the existing definition.  Also, due to an EF bug, the enum should have the same name as the external type.

Again, we can query and save these entities:

C#
var mgr = new EnumTestEntities();
mgr.AddEntity(new Department { Name = DepartmentNames.Math, MeetingDay = DayOfWeek.Wednesday });
mgr.SaveChanges();

var depts = mgr.Departments.Where(d => d.MeetingDay == DayOfWeek.Wednesday).ToList();

Troubleshooting

  • You can use enum types in n-tier applications without additional markup.  You will receive a serialization error if the enum type is not defined on a tier, or if a member value is unknown.  Unknown member values may occur, for example, when the database contains additional values not defined in the enum.  

  • If you're using an enum defined in an assembly normally excluded from DevForce probing, such as System.DayOfWeek defined in mscorlib, in an n-tier application you'll need to add this type as a known type.

  • You cannot use an external enum type in a Contains clause.  This is an EF bug.


Tags: Model
Created by DevForce on December 18, 2012 15:02

This wiki is licensed under a Creative Commons 2.0 license. XWiki Enterprise 3.2 - Documentation. Copyright © 2020 IdeaBlade