Cómo mapear enum como cadena en la base de datos

Mi mesa:

create table MyTable (
    Id int identity(1,1) not null,
    MyStatus char(2) not null
)
insert into MyTable(MyStatus) select 'A'

Clase y enumeración:

public class MyTable
{
    public virtual int Id { get; set; }
    public virtual MyTableStatus MyStatus { get; set; }
}

public enum MyTableStatus
{
    A,
    B
}

Cartografía:

public MyTableMap()
{
    Id(x => x.Id);
    Map(x => x.MyStatus);
}

Cuando ejecuto la siguiente prueba, obtengo System.FormatException: la cadena de entrada no tenía el formato correcto ...

[Test]
public void Blah()
{
    MyTable myTable = Session.Get<MyTable>(1);
    Assert.That(myTable.MyStatus, Is.EqualTo(MyTableStatus.A));
}

¿Cuál es la forma correcta de asignar una enumeración a su representación de cadena en la base de datos?

Editar: estoy escribiendo mi aplicación en una base de datos existente, que no puedo modificar fácilmente porque también la utilizan otras aplicaciones. Entonces, algunos campos en la base de datos (que me gustaría representar como enumeraciones en mi aplicación) son de tipo int y algunos de tipo char (2).

preguntado el 09 de enero de 11 a las 00:01

También me gustaría saber, incluido el trabajo con una base de datos que usa cadenas e ints para diferentes enumeraciones. (Solo lo hice funcionar con ints) -

2 Respuestas

Debe crear un IUserType personalizado para convertir una enumeración en su representación de cadena y viceversa. Hay una buen ejemplo en C # aquí y un ejemplo en VB.NET para trabajar con enumeraciones aquí (desplácese hacia abajo para implementar IUserType).

Respondido el 09 de enero de 11 a las 17:01

No hay EnumStringType que hace exactamente esto. Mira esto pregunta para ver un ejemplo de cómo usar esto. - Darío

Bueno, hasta donde yo sé, NHibernate almacena enumeraciones como cadenas solo en la base de datos de forma predeterminada. Creo que sé cuál es el problema aquí. La forma en que está creando la tabla es incorrecta.

si está usando Nhibernate, use la función de configuración de compilación para crear las tablas en lugar de crear las tablas manualmente y luego verá que su enumeración se almacena como una cadena.

Usamos enumeraciones ampliamente en nuestra aplicación y tiene sentido para nosotros almacenarlas como cadenas en la base de datos. Las razones son simples si agrego un nuevo valor a una enumeración, entonces, si los valores predeterminados no están configurados, mi código y mis datos están estrechamente acoplados, lo que definitivamente no querría.

SimpleConfig.ExposeConfiguration(c => new SchemaExport(c).Create(false, true)).BuildConfiguration();

Además, en lugar de usar char para su cadena, puede usar varchar para la propiedad.

Después de la actualización: ¿No pueden hacer algún tipo de manipulación antes de almacenarlo en la base de datos? Por lo tanto, cuando desee almacenar las nuevas enumeraciones de caracteres, escriba una función que genere un valor int para usted y almacene esto en la propiedad y ahora guárdelo o si desea hacerlo simple, la función puede tener un cambio de mayúsculas y minúsculas.

Entonces, lo que hace es que no tiene un get en esta propiedad que se recupera de la base de datos, sino que agrega una nueva propiedad en la clase Status que básicamente tiene la lógica de obtener la enumeración adecuada.

¿Crees que es una buena idea?

Espero que esto ayude.

Respondido el 09 de enero de 11 a las 15:01

Prefiero almacenar Enums como TINYINT, pero mi problema es que tengo dos valores que se almacenan como VARCHAR. NH no mapeará estos :( Así que no sé cómo usar tanto String e Int Enums juntos. - Phill

El mismo problema aquí: algunas 'enumeraciones' son int y otras son caracteres. Actualicé mi pregunta. - sventevit

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.