example enum como clase acceder c# java database enums persistence

como - enum definition c#



Mejores prácticas para usar y persistir enums (10)

He visto varias preguntas / discusiones aquí sobre la mejor manera de manejar y persistir enum-like valores (por ejemplo Persisting datos adecuados para enumeraciones , Cómo persistir una enumeración usando NHibernate ), y me gustaría preguntar cuál es el consenso general .

En particular:

  • ¿Cómo deben manejarse estos valores en el código?
  • ¿Cómo deberían persistir en una base de datos (como texto / como número)?
  • ¿Cuáles son las ventajas y desventajas de las diferentes soluciones?

Nota: Moví las explicaciones originalmente incluidas en esta pregunta a una respuesta.


Almacenar el valor de texto de una enumeración en una base de datos es menos preferido que almacenar un número entero, debido al espacio adicional requerido y la búsqueda más lenta. Es valioso en el sentido de que tiene más significado que un número, sin embargo, la base de datos es para el almacenamiento, y la capa de presentación es para que las cosas se vean bien.


Bueno, desde mi experiencia, el uso de enumeraciones para cualquier cosa que no sea para pasar opciones (como indicadores) a una llamada al método inmediato, da como resultado la switch en algún momento.

  • Si va a utilizar la enumeración en todo su código, puede terminar con un código que no es tan fácil de mantener (la infame sentencia de switch )
  • Extender enumeraciones es un dolor. Agregas un nuevo ítem enum y terminas revisando todo tu código para verificar todas las condiciones.
  • Con .NET 3.5, puede agregar métodos de extensión a enumeraciones para que se comporten un poco más como clases. Sin embargo, agregar una funcionalidad real de esta manera no es tan fácil ya que todavía no es una clase (terminarías usando los switch en tus métodos de extensión si no en otra parte).

Entonces, para una entidad tipo enum con un poco más de funcionalidad, debería tomarse un tiempo y crearla como una clase, con varias cosas en mente:

  • Para hacer que su clase se comporte como una enumeración, puede forzar a cada clase derivada a crear instancias como Singleton o anular Igual para permitir la comparación de valores de diferentes instancias.
  • Si su clase es enumática, debería significar que no debería contener un estado serializable, la deserialización debería ser posible solo por su tipo (una especie de "ID", como usted dijo).
  • La lógica de persistencia debe limitarse a la clase base solamente, de lo contrario, extender su "enumeración" sería una pesadilla. En caso de que eligiera el patrón Singleton, necesitaría asegurar una deserialización adecuada en instancias singleton.

Cada vez que te encuentres usando "números mágicos" en el código, cambia a enumeraciones. Además de ahorrar tiempo (ya que la magia desaparecerá cuando aparezcan los errores ...) le ahorrará los ojos y la memoria (las enumeraciones significativas hacen que el código sea más legible y autodocumentado), ya que adivine qué: usted es probablemente la persona que debe mantener y desarrollar tu propio código


El artículo inicial me parece bien. Aún así, según los comentarios, parece que algunos comentarios sobre las enumeraciones de Java podrían aclarar algunas cosas.

El tipo Enum en Java es una clase por definición, pero muchos programadores tienden a olvidar esto, porque lo relacionan con "una lista de valores permitidos" como en otros idiomas. Es más que eso.

Entonces, para evitar esas declaraciones de cambio, podría ser razonable poner algún código y métodos adicionales en la clase enum. Casi nunca hay necesidad de crear una "clase real enum" separada.

Considere también el punto de la documentación: ¿desea documentar el significado real de su enumeración en la base de datos? ¿En el código fuente que refleja los valores (su tipo de enumeración) o en alguna documentación externa? Yo personalmente prefiero el código fuente.

Si desea presentar los valores enum como enteros en la base de datos debido a la velocidad o el motivo que sea, esa asignación también debe residir en la enumeración de Java. Obtendrá la asignación de nombre de cadena de forma predeterminada, y he estado satisfecho con eso. Hay un número ordinal asociado con cada valor enum, pero usarlo directamente como una asignación entre código y base de datos no es muy brillante, porque ese número ordinal cambiará si alguien reordena los valores en el código fuente. O agrega valores enum adicionales entre los valores existentes. O elimina algún valor.

(Por supuesto, si alguien cambia el nombre de la enumeración en el código fuente, el mapeo de cadenas predeterminado también se agriará, pero es menos probable que ocurra accidentalmente. Y si es necesario, puede protegerlo más fácilmente si aplica alguna comprobación de tiempo de ejecución y verifique las restricciones en la base de datos como se sugiere aquí.)


En el manejo de código para C # te has perdido la definición de acarrear el valor 0. Casi siempre declaro mi primer valor como:

public enum SomeEnum { None = 0, }

Para servir como un valor nulo. Debido a que el tipo de respaldo es un número entero y un entero por defecto es 0, por lo que es enormemente útil en muchos lugares para saber si una enumeración ha sido programada o no.


Estoy de acuerdo con mucho de lo que dices. Una cosa que me gustaría añadir, sin embargo, sobre la persistencia de las enumeraciones: no creo que la generación de las enumeraciones en tiempo de compilación a partir de los valores DB sea aceptable, pero también creo que el control del tiempo de ejecución no es una buena solución . Definiría un tercer medio: tener una prueba de unidad que verificará los valores de la enumeración contra la base de datos. Esto evita la divergencia "casual" y evita la sobrecarga de verificar las enumeraciones en la base de datos cada vez que se ejecuta el código.


Imho, en cuanto a la parte del código:

Siempre debe usar el tipo "enum" para sus enumeraciones, básicamente obtendrá muchos regalos si lo hace: seguridad tipo, encapsulación y evitación de conmutadores, el soporte de algunas colecciones como EnumSet y EnumMap y claridad de código.

en cuanto a la parte de persistencia, siempre puede persistir la representación de cadena de la enumeración y cargarla de nuevo utilizando el método enum.valueOf (String).


Java o C # siempre deben usar enumeraciones en el código. Descargo de responsabilidad: Mi fondo es C #.

Si el valor debe persistir en una base de datos, los valores integrales de cada miembro de enumeración deben definirse explícitamente para que un cambio posterior en el código no altere accidentalmente los valores enum traducidos y, por lo tanto, el comportamiento de la aplicación.

Los valores siempre deben persistir en una base de datos como valores integrales, para proteger contra la refactorización de nombres enum. Guarde la documentación de cada enumeración en una wiki y agregue un comentario al campo de la base de datos que apunta a la página wiki que documenta el tipo. También agregue documentación XML al tipo de enumeración que contiene un enlace a la entrada wiki para que esté disponible a través de Intellisense.

Si usa una herramienta para generar código CRUD, debe ser capaz de definir un tipo de enumeración para usar en una columna, de modo que los objetos de código generados siempre usen los miembros enumerados.

Si se debe aplicar una lógica personalizada para un miembro de enumeración, tiene algunas opciones:

  • Si tiene un enum MyEnum, cree una clase estática MyEnumInfo que ofrezca métodos de utilidad para descubrir información adicional sobre el miembro enum, mediante instrucciones de conmutación o cualquier otro medio necesario. Agregar "Información" al final del nombre enum en el nombre de la clase asegura que estarán uno al lado del otro en IntelliSense.
  • Decore los miembros de la enumeración con atributos para especificar parámetros adicionales. Por ejemplo, hemos desarrollado un control EnumDropDown que crea un menú desplegable de ASP.NET lleno de valores de enumeración, y un EnumDisplayAttribute especifica el texto de visualización muy bien formateado para usar para cada miembro.

No he intentado esto, pero con SQL Server 2005 o posterior, en teoría podría registrar el código C # con la base de datos que contendría la información enum y la capacidad de convertir valores en enumeraciones para usar en vistas u otras construcciones, haciendo un método de traducción del datos de una manera más fácil de usar para los DBA.


Sé que este es un foro antiguo, ¿y si la base de datos pudiera tener otras cosas integradas directamente? Por ejemplo, cuando el DB resultante es el ÚNICO propósito del código. Entonces, definirás las enumeraciones en cada integración. Mejor entonces tenerlos en la base de datos. De lo contrario, estoy de acuerdo con la publicación original.


Intenté resumir mi comprensión. No dude en editar esto si tiene alguna corrección. Así que aquí va:

En el código

En el código, las enumeraciones se deben manejar utilizando el tipo de enumeración nativo del idioma (al menos en Java y C #), o usando algo como el "patrón de enum de tipo seguro" . Se desaconseja el uso de constantes simples (enteros o similares), ya que se pierde la seguridad del tipo (y dificulta la comprensión de qué valores son datos legales, por ejemplo, un método).

La elección entre estos dos depende de cuánta funcionalidad adicional se debe adjuntar a la enumeración:

  • Si desea poner un montón de funcionalidades en la enumeración (lo cual es bueno, porque evita el cambio () encendido todo el tiempo), una clase suele ser más apropiada.
  • Por otro lado, para valores sencillos como enum, la enumeración del lenguaje suele ser más clara.

En particular, al menos en Java una enumeración no puede heredar de otra clase, por lo que si tiene varias enumeraciones con comportamientos similares que le gustaría poner en una superclase, no puede usar las enumeraciones de Java.

Enums persistentes

Para persistir las enumeraciones, a cada valor enum se le debe asignar una ID única. Esto puede ser un número entero o una cadena corta. Se prefiere una cadena corta, ya que puede ser mnemónica (hace que sea más fácil para los DBA, etc., comprender los datos sin procesar en el db).

  • En el software, cada enumeración debe tener funciones de mapeo para convertir entre la enumeración (para usar dentro del software) y el valor de ID (para persistir). Algunos marcos (por ejemplo, (N) Hibernate) tienen un soporte limitado para hacer esto automáticamente. De lo contrario, debes ponerlo en el tipo / clase enum.
  • La base de datos debe contener (idealmente) una tabla para cada enumeración que enumere los valores legales. Una columna sería la ID (ver arriba), que es la PK. Las columnas adicionales pueden tener sentido para, por ejemplo, una descripción. Todas las columnas de la tabla que contendrán valores de esa enumeración pueden entonces usar esta "tabla de enumeración" como FK. Esto garantiza que los valores de enum incorrectos nunca pueden persistir, y permite que el DB "se soporte por sí mismo".

Un problema con este enfoque es que la lista de valores legales enum existe en dos lugares (código y base de datos). Esto es difícil de evitar y, por lo tanto, a menudo se considera aceptable, pero existen dos alternativas:

  • Solo mantenga la lista de valores en el DB, genere el tipo de enumeración en tiempo de compilación. Elegante, pero significa que se requiere una conexión de base de datos para que se ejecute una construcción, lo que parece problemático.
  • Defina la lista de valores en el código para ser autoritativo. Verifique los valores en el DB en tiempo de ejecución (generalmente al inicio), se queje / aborte cuando no coinciden.