2011-02-02 30 views
10

Aquí está mi problema. Una clase que define un orden tiene una propiedad llamada PaymentStatus, que es un enum define así:Azure Table Storage, WCF Service y Enum

public enum PaymentStatuses : int 
    { 
     OnDelivery = 1, 
     Paid = 2, 
     Processed = 3, 
     Cleared = 4 
    } 

Y más adelante, en la propia clase, la definición de la propiedad es muy simple:

public PaymentStatuses? PaymentStatus { get; set; } 

Sin embargo, si intento para salvar una orden a la tabla de almacenamiento de Azure, me sale el siguiente excepción:

System.InvalidOperationException: The type Order+PaymentStatuses' has no settable properties. 

en este punto pensé USI ng enum no es posible, pero una rápida búsqueda en Google devuelve la siguiente: http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/7eb1a2ca-6c1b-4440-b40e-012db98ccb0a

Esta página muestra dos respuestas, una de las cuales parece ignorar los problemas y sugiere que el uso de un enum en Azure Storage está muy bien.

Ahora, NO NECESITO almacenar el enum en Azure Table Storage como tal, podría almacenar también un correspondiente int, sin embargo, sí necesito que esta propiedad esté expuesta en el servicio WCF.

He intentado hacer el uso de la propiedad get y set para devolver el enum de un integer almacenado, y quitar esta propiedad de Azure utilizando el evento WritingEntity en mi DataContext, pero me da esa excepción antes del evento para esta entidad Está despedido.

En este punto, estoy perdido, no sé qué más puedo hacer para tener esta propiedad en WCF como enum, pero tengo la tienda Azure solo en int.

Respuesta

15

Enum no es compatible. Aunque se define como un int, en realidad no es un tipo integral admitido por Table Storage. Here is the list of types supported. Una enumeración es solo una expresión de cadena de un número integral con un sabor orientado a objetos.

Puede almacenar int en el almacenamiento de tablas y luego encubrirlo usando Enum.Parse.

0

sólo sugerencias ...

que recordar que en WCF tiene que marcar las enumeraciones con atributos especiales: http://msdn.microsoft.com/en-us/library/aa347875.aspx

Además, cuando se declara PaymentStatuses? PaymentStatus, que está declarando Nullable<PaymentStatuses> PaymentStatus. El sintax ? es solo azúcar sintáctico. Intente eliminar el ? y vea qué sucede (puede agregar un PaymentStatuses.NoSet = 0, porque el valor predeterminado para un Int32 es 0).

Buena suerte.

+0

Esto no funciona. No tengo problemas con el WCF como tal. Si creo un DataContract y defino una enumeración, funciona bien. Lo que necesito es que la enumeración funcione de alguna manera con Azure Storage Tables. – Shaamaan

3

ya estaba teniendo este mismo problema cambié mi propiedad que fue anterior a enumerar int.Ahora esta propiedad int analiza el int entrante y lo guarda en un variale del mismo tipo de enumeración por lo que ahora el código que se

public CompilerOutputTypes Type 
{get; set;} 

es cobrada a

private CompilerOutputTypes type; 
public int Type 
{ 
    get {return (int)type;} 
    set { type = (CompilerOutputTypes)value; } 
} 
+1

En mi caso, esta no es una solución válida: un servicio WCF que utiliza la enumeración aún necesita operar en enteros en lugar de enumeraciones. – Shaamaan

0

solución Parvs me puso en el camino correcto pero tuve algunos ajustes menores.

private string _EnumType; 
private EnumType _Type; 

//********************************************* 
//********************************************* 
public string EnumType 
{ 
    get { return _Type.ToString(); } 
    set 
     { 
      _EnumType = value; 
      try 
      { 
       _Type = (EnumType)Enum.Parse(typeof(EnumType), value);  
      } 
      catch (Exception) 
      { 
       _EnumType = "Undefined"; 
       _Type = [mynamespace].EnumType.Undefined;     
      }       
     } 
    } 
11

Aquí hay una solución simple: (pública)

public int MyEnumValue { get; set; } //for use by the Azure client libraries only 
[IgnoreProperty] public MyEnum MyEnum 
{ 
    get { return (MyEnum) MyEnumValue; } 
    set { MyEnumValue = (int) value; } 
} 

Hubiera sido mejor si un valor de respaldo simple podría haber sido empleado en lugar de una propiedad adicional - sin la molestia de anular ReadEntity/WriteEntity por supuesto. Abrí un user voice ticket que facilitaría eso, por lo que es posible que desee subirlo.

0

Me encontré con un problema similar y he implementado una API de acoplador/recomponedor de objetos genérico que aplanará sus entidades complejas en diccionarios planos EntityProperty y los hará escribibles para el almacenamiento de tabla, en la forma de DynamicTableEntity.

La misma API recompondrá todo el objeto complejo desde el diccionario EntityProperty del DynamicTableEntity.

Esto es relevante a su pregunta porque la API ObjectFlattenerRecomposer apoya aplanamiento tipos de propiedad que normalmente no son escribibles a Azure Storage Table como Enum, TimeSpan, todos los tipos, Nullableulong y uint convirtiéndolos en EntityProperties se pueda escribir.

La API también maneja la conversión de nuevo al objeto complejo original del EntityProperty Dictionary aplanado. Todo lo que el cliente necesita hacer es decirle a la API, tengo este EntityProperty Diccionario que acabo de leer de Azure Table (en la forma de DynamicTableEntity.Properties), puede convertirlo en un objeto de este tipo específico. La API recompondrá el objeto complejo completo con todas sus propiedades, incluidas las propiedades 'Enum' con sus valores correctos originales.

Todo este aplanamiento y recomposición del objeto original se realiza de forma transparente para el cliente (usuario de la API). El cliente no necesita proporcionar ningún esquema o conocimiento a la API ObjectFlattenerRecomposer sobre el objeto complejo que quiere escribir, simplemente pasa el objeto a la API como 'objeto' para aplanarlo. Al convertirlo de nuevo, el cliente solo necesita proporcionar el tipo de objeto real al que quiere convertir el diccionario aplanado EntityProperty. El método genérico ConvertBack de la API simplemente recompondrá el objeto original de Tipo T y lo devolverá al cliente.

Vea el ejemplo de uso a continuación. Los objetos no necesitan implementar ninguna interfaz como 'ITableEntity' o heredar de una clase base particular tampoco. No necesitan proporcionar un conjunto especial de constructores.

Blog:https://doguarslan.wordpress.com/2016/02/03/writing-complex-objects-to-azure-table-storage/

Nuget paquete:https://www.nuget.org/packages/ObjectFlattenerRecomposer/

Uso:

//Flatten object (ie. of type Order) and convert it to EntityProperty Dictionary 
Dictionary<string, EntityProperty> flattenedProperties = EntityPropertyConverter.Flatten(order); 

// Create a DynamicTableEntity and set its PK and RK 
DynamicTableEntity dynamicTableEntity = new DynamicTableEntity(partitionKey, rowKey); 
dynamicTableEntity.Properties = flattenedProperties; 

// Write the DynamicTableEntity to Azure Table Storage using client SDK 

//Read the entity back from AzureTableStorage as DynamicTableEntity using the same PK and RK 
DynamicTableEntity entity = [Read from Azure using the PK and RK]; 

//Convert the DynamicTableEntity back to original complex object. 
Order order = EntityPropertyConverter.ConvertBack<Order>(entity.Properties); 
Cuestiones relacionadas