En este artículo mostraré como usar tipos enum con Entity Framework Code First, además de mostrar cómo usar enums en una consulta LINQ.

El soporte de enumeraciones fue introducido en Entity Framework 5. Para usar todas las nuevas características que trae el EF 5.0 (como enumeraciones, tipos de datos espaciales y funciones tabulares), debe configurar el proyecto para que utilice la versión .NET Framework 4.5. Recordemos que Visual Studio 2012, por defecto, utiliza .NET 4.5.

Por este motivo no se puede utilizar el Visual Studio 2010 para aplicar estas nuevas características, aun cuando estemos utilizando la versión Entity Framework 5.0.

En Entity Framework, una enumeración puede tener los siguientes tipos subyacentes: Byte, Int16, Int32, Int64 o SByte.

Creación de la aplicación ejemplo

  • Abrimos Visual Studio 2012
  • En el menú File, hacemos click en New, y luego en Project
  • En la ventana New Project, en el panel izquierdo, hacemos click en Visual C#, y luego seleccionamos la plantilla Console Application
  • Entramos SoporteEnumCodeFirst como el nombre del proyecto y luego hacemos click en OK
  • Definimos un nuevo modelo de datos usando Code First, para eso, agregamos una nueva clase a nuestro proyecto, llamada Course y dentro de este archivo, además agregamos la enumeración CourseNames. El archivo completo es el siguiente:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SoporteEnumCodeFirst
{
    public enum CourseNames
    {
        [Description("MVC 4")] MVC4 = 10285,
        [Description("HTML 5")] HTML5 = 10286,
        [Description("Windows Comunication Foundation")] WCF = 10287,
        [Description("Entity Framework 5.0")] EntityFramework5 = 10288     
    }   

    public class Course
    {
        public int CourseId { get; set; }
        public CourseNames Name { get; set; }
        public Byte DuracionDias { get; set; }
    }
}
  • Definimos el contexto, es decir una clase, llamada EnumContext, derivada de DbContext, para eso, agregamos una referencia al assembly EntityFramework (ya que las clases DbContext y DbSet están definidas en este assembly), utilizando el paquete NuGet EntityFramework. Al hacer esto, además de agregar el assembly EntityFramework, también son agregadas referencias a los assemblies System.ComponentModel.DataAnnotations y System.Data.Entity. Arriba del código de la clase EnumContext escribimos la sentencia using que importa el namespace System.Data.Entity. El código de la clase EnumContext queda definido así:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace SoporteEnumCodeFirst
{
   public partial class EnumContext : DbContext
   {
        public EnumContext():base("EF5EnumDB")
        { }

        public DbSet Courses { get; set; }
    }
}

Como vemos en el código de arriba, generaremos la base de datos con el nombre EF5EnumDB. Esto se obtiene llamando al constructor de la clase base (DbContext), pasándole el nombre que queremos darle a la base de datos como parámetro.

  • En el archivo Program.cs, agregamos el siguiente código a la función Main. El código agrega un nuevo objeto del tipo curso al contexto y luego graba los datos. Por último el código también ejecuta una consulta LINQ que devuelve un curso donde el nombre del curso es el valor de la enumeración CourseNames.EntityFramework5. A continuación el código completo de la clase Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SoporteEnumCodeFirst
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new EnumContext())
            {
                db.Courses.Add(new Course {
                      Name = CourseNames.EntityFramework5, 
                      DuracionDias=10 });
                db.SaveChanges();
                
                var miCurso = 
                      (from d in db.Courses
                      where d.Name == CourseNames.EntityFramework5
                      select d).FirstOrDefault();

                Console.WriteLine("CourseID: {0} Nombre: {1}", 
                      miCurso.CourseId, miCurso.Name);
            }
        }

        public static string GetDescription(Enum value)
        {
            FieldInfo fi = value.GetType().GetField(value.ToString());
            DescriptionAttribute[] attributes = 
                      (DescriptionAttribute[])fi.GetCustomAttributes(
                            typeof(DescriptionAttribute), false);
            return (attributes.Length > 0) ? 
                      attributes[0].Description : 
                      value.ToString();
        }
    }
}

Al ejecutar el programa, se obtiene la salida que se observa en el Figura 1:

Salida del programa con soporte para Enumeraciones para EF 5 Code First
Figura 1 - Salida del programa con soporte para Enumeraciones para EF 5 Code First

Como observamos en la figura 2, si abrimos el SQL Management Studio, comprobaremos que efectivamente, se creo una nueva base de datos con el nombre EF5EnumDB y que dicha base de datos tiene una tabla llamada Courses y el campo Name se definió como un int

Al ejecutarse el programa, se crea la base de datos
Figura 2 - La base de datos creada, se generó con una tabla Courses y el campo Name es
del tipo int

En la figura 3 observamos que el valor insertado en el campo Name es precisamente el valor numérico definido en la enumeración (para nuestro caso 10288)

El valor insertado en el campo Name es el valor numérico definido en la enumeración
Figura 3 - El valor insertado en el campo Name es el valor numérico definido en la enumeración
Una aclaración sobre las enumeraciones: Los miembros de una enumeración deben ser identificadores válidos, por lo que no pueden contener espacios o caracteres especiales. Pero... y si queremos recuperar los miembros de la enumeración con espacios y caracteres especiales... ¿qué debemos hacer?
Como se ve en el código de la definición de la enumeración, esto lo podemos lograr utilizando la clase DescriptionAttribute, pasándole una descripción completa de cada valor de la enumeración (por ejemplo para el valor "EntityFramework5", le pasamos "Entity Framework 5.0" o para "WCF", le pasamos "Windows Communication Foundation".
Para recuperar la descripción, usamos Reflexión, como se ve en el código de la función GetDescription(Enum value)
respag   
Panamá © 2012
Haga su donación para colaborar con La Escuela del Programador

La Escuela del Programador es un sitio web sin anuncios, sin ánimo de lucro, no es un sitio web comercial. Es el sueño de compartir con todos, muchos años de una gran pasión. Si realmente encuentra este sitio útil y lo aprovecha, le pido su generosa y no importa cuán modesta colaboración, simplemente para afrontar los costos de mantener este sitio disponible en internet.
No deseo lucrar con este sitio, ya que lo hago desinteresadamente, sólo le pido que, si puede, aporte (desde un dólar hasta lo que crea que puede dar), para afrontar los costos de dominio y hosting. Muchísimas gracias y ojalá juntos podamos hacer un sitio que sea una buena fuente de aprendizaje de programacíon en español.

Si no se siente en condiciones de colaborar, igualmente será bienvenido al sitio, es libre para todos y será un placer que encuentre mis artículos provechosos, pero si realmente me ayuda con una donación minima, seguramente, colaborará para que La Escuela del Programador se mantenga en la Web y crezca, conviertiendo a este sitio hecho con mucha pasión, dedicación y esfuerzo, en una buena fuente de aprendizaje.

Mis saludos cordiales y gracias por interesarse en mi sitio.

Rubén E. Spagnuolo
respag
Panamá - © 2012