2011-01-09 22 views
6

Mi mesa:cómo asignar enumeración como cadena en la base de datos

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 
} 

Mapping:

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

Cuando ejecuto la siguiente prueba, me sale System.FormatException: la cadena de entrada no estaba en un 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 cadenas 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 es utilizada por 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).

+0

También me gustaría saber, incluido el trabajo con una base de datos que utiliza cadenas y entradas para diferentes enumeraciones. (Solo lo tengo trabajando con ints) – Phill

Respuesta

5

Debe crear un IUserType personalizado para convertir una enumeración en su representación de cadena y viceversa. Hay un good example in C# here y un example in VB.NET for working with enums here (desplácese hacia abajo para implementar IUserType).

+0

Hay [EnumStringType] (https : // github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Type/EnumStringType.cs) que hace esto. Consulte esta [pregunta] (http://stackoverflow.com/questions/335533/normalizing-enumstringtype-in-nhibernate) para ver un ejemplo de cómo usar esto. – Darius

0

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

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

Usamos enumeraciones extensamente en nuestra aplicación y tiene sentido que las almacenemos como cadenas en la base de datos. Las razones son simples si agrego un nuevo valor a un enum tom, y si no se establecen los valores predeterminados, entonces mi código y mis datos están estrechamente acoplados, lo que definitivamente no me gustaría.

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

También 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 almacenarla en la base de datos? Por lo tanto, cuando desee almacenar las nuevas enumeraciones, escriba una función que genere un valor int para usted y almacénelo en la propiedad y guárdelo o, si quiere hacerlo simple, la función puede tener una caja de conmutadores.

Así que lo que haces es que no tienes un get en esta propiedad que se recupera del db sino que agregas 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.

+0

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 String e Int Enums juntos. – Phill

+0

El mismo problema aquí - algunas 'enums' son int y algunas son caracteres. Se ha actualizado mi pregunta. – sventevit

Cuestiones relacionadas