2009-03-23 11 views
15

Tome la siguiente bandera EnumMapeo de una bandera de bits Enumeración de Nhibernate

[Flags] 
enum Permssions 
{ 
    CanComment = 1, 
    CanEdit = 2, 
    CanDelete = 4, 
    CanRemoveUsers = 8, 
    All = CanComment | CanEdit | CanDelete | CanRemoveUsers 
} 

En NHibernate he asignado a una enumeración antes de usar:

<property type="n.Permssions, n.Permssions" 
name="Permssions" column="Permssions"></property> 

Mi pregunta es, ¿Cómo puedo asignar una campo de bit a campo de bandera usando NHibnerate?

Respuesta

2

Creo que la mejor opción para esto sería usar un Custom User Type. En el que puede asignar el Enum de su clase a esas dos columnas. Aquí es un ejemplo del uso ICompositeUserMap que puede ser utilizado como una guía:

Aunque en su caso, al implementar IUserType podría ser suficiente.

+0

No hay necesidad de un tipo de usuario personalizado - NHibernate sabe cómo manejar los enum Flags. Eche un vistazo a la respuesta principal. –

0

esto no responde a su pregunta exactamente, pero podría ser más fácil de usar una propiedad Int32 en su clase y la cartografía, y el uso de una clase estática de las constantes de esta manera de manejar los valores de código:

public static class Permissions 
{ 
    public const int CanComment = 0x1; 
    public const int CanEdit = 0x2; 
    public const int CanDelete = 0x4; 
    public const int CanRemoveUsers = 0x8; 
    public const int All = CanComment | CanEdit | CanDelete | CanRemoveUsers; 
} 

Sé que esto no es ideal, ya que no restringe a los usuarios a los valores de enum fijos, y te obliga a tratar con raw en el código, pero creo que Hibernate tendrá problemas con una enumeración bit a bit. Intentará asignar un valor en la base de datos a un valor enum específico. Si encuentra un valor en la base de datos que no ha enumerado explícitamente, probablemente se ahogue. P.ej. si encuentra un "3" en la base de datos, no podrá volver a asignarlo a un valor de enumeración, a menos que enumere explícitamente cada combinación, como CanCommentAndEdit, CanCommentAndEditAndDelete, etc. Esto probablemente anula el propósito de utilizar la enumeración bit a bit .

0

Tendría un campo int privado para la persistencia NHibernate y una propiedad Getter/Setter pública para la enumeración de indicador que lee y escribe en el campo int. (NHibernate se puede configurar para que funcione con campos privados)

De esta manera, no tiene que recurrir a la magia vudú ni a las constantes sucias para hacer el trabajo.

9

Cuando marco una enumeración, y esta enumeración tiene un valor de respaldo de tipo 'int', simplemente asigno mi propiedad enum a un campo int en la base de datos. No me he encontrado con problemas para esto.
He hecho esto para enum de banderas también, y esto simplemente funciona sin problemas. Cuando combine ciertos indicadores, NHibernate mantendrá la "combinación" de esos indicadores en la columna especificada en la base de datos.
Cuando recupera la instancia que tiene una propiedad de 'flag enums', NHibernate la reconstituirá con la combinación correcta.
Por ejemplo, si el DB contiene '3', NHibernate poblará su propiedad con la combinación de los valores apropiados.
De hecho, dejo que NHibernate a resolverlo todo por sí mismo:

<property name="OnCallType" column="OnCallType" /> 

donde la columna OnCallType es de tipo int en mi base de datos, y la propiedad OnCallType es un tipo enumerado que tiene atribuyen las banderas.

+0

¿qué pasa con el efecto fantasma de nhibernate? – giammin

1

Esto resolvió el problema para mí:

En el mapeo de clase I maped a un tipo personalizado con el nombre del tipo enum.

Map(x => x.MyEnumProperty).CustomType<EnumType>(); 
Cuestiones relacionadas