2011-02-02 6 views
10

Oto mój problem. Klasa, która definiuje kolejność ma właściwość o nazwie PaymentStatus, który jest enum zdefiniowane tak:Przechowywanie tabel Azure, usługa WCF i Enum

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

a później, w samej klasie, definicja Obiekt jest bardzo prosta:

public PaymentStatuses? PaymentStatus { get; set; } 

jednak, gdy próbuję zapisać rozkaz do Azure Storage Table, pojawia się następujący wyjątek:

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

w tym momencie myślałem USI ng enum nie jest możliwe, ale szybkie wyszukiwanie Google wrócił to: http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/7eb1a2ca-6c1b-4440-b40e-012db98ccb0a

Strona ta wymienia dwie odpowiedzi, z których jeden wydaje się ignorować problemy i sugeruje, że stosując enum w Azure Storage jest w porządku.

Teraz, nie muszę przechowywać enum w pamięci podręcznej Azure Table jako takiej, mógłbym równie dobrze przechowywać odpowiadający int, jednak potrzebuję tej właściwości, aby być odsłoniętym w usłudze WCF.

Próbowałem dzięki czemu korzystanie własności get i set zwrócić enum od zapisanego integer i usunąć tę właściwość z Azure za pomocą zdarzenia WritingEntity na moim DataContext, ale pojawia się ten wyjątek przed wydarzeniem dla tego podmiotu jest zwolniony.

W tym momencie jestem na stracie, nie wiem, co jeszcze mogę zrobić, aby ta właściwość w WCF jako enum, ale mieć sklep Azure tylko int.

Odpowiedz

15

Enum nie jest obsługiwany. Mimo że jest zdefiniowany jako int, to naprawdę nie jest typem integralnym obsługiwanym przez Table Storage. Here is the list of types supported. Wyliczenie jest po prostu ciągiem wyrażającym liczbę całkowitą o charakterze obiektowym.

Możesz przechowywać w pamięci podręcznej int, a następnie ukryć ją za pomocą programu Enum.Parse.

0

zaledwie sugestie ...

Pamiętam, że w WCF trzeba zaznaczyć stałe teksty z wyróżnikiem: http://msdn.microsoft.com/en-us/library/aa347875.aspx

Również, gdy zadeklarujesz PaymentStatuses? PaymentStatus, jesteś deklarowania Nullable<PaymentStatuses> PaymentStatus. Sintax ? to po prostu cukier syntaktyczny. Spróbuj usunąć ? i zobacz, co się stanie (możesz dodać PaymentStatuses.NoSet = 0, ponieważ domyślna wartość dla Int32 to 0).

Powodzenia.

+0

To nie działa. Nie mam problemów z WCF jako takie. Jeśli utworzę DataContract i zdefiniuję w nim wyliczenie, działa dobrze. Potrzebuję, aby wyliczenie w jakiś sposób działało z Tabelami pamięci Azure. – Shaamaan

3

ya miałem ten sam problem Zmieniłem moją własność, która była wcześniejsza enum do int.teraz to int nieruchomość analizuje przychodzące int i zapisuje go w variale tego samego typu enum więc teraz kod, który był

public CompilerOutputTypes Type 
{get; set;} 

jest chaged do

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

W moim przypadku nie jest to prawidłowe rozwiązanie: usługa WCF, która używa enum nadal musi działać na liczbach całkowitych zamiast wyliczenia. – Shaamaan

0

rozwiązania Parvs umieścić mnie na właściwe tory ale miałem drobne poprawki.

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

Oto proste obejście:

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; } 
} 

Byłoby ładniej, jeśli prosta wartość podkład mogły być stosowane zamiast dodatkowego (! Publicznym) nieruchomości - bez kłopotów z nadrzędnymi ReadEntity/WriteEntity oczywiście. Otworzyłem kod user voice ticket, który ułatwiłby to, więc możesz go przejąć.

0

Natknąłem się na podobny problem i zaimplementowałem interfejs API rozpłaszczania/ponownego generowania obiektów, który spłaszcza złożone jednostki w płaskie słowniki EntityProperty i umożliwia ich zapisywanie w pamięci tabeli, w postaci DynamicTableEntity.

Ten sam interfejs API ponownie skomponuje cały obiekt złożony z powrotem ze słownika EntityProperty z DynamicTableEntity.

Jest to istotne pytanie, ponieważ obsługuje API ObjectFlattenerRecomposer spłaszczenie rodzaje nieruchomości, które nie są zazwyczaj zapisywany w Azure Storage Table jak Enum, TimeSpan wszystkie Nullable typy ulong i uint poprzez przekształcenie ich w zapisywalnych EntityProperties.

Interfejs API obsługuje również konwersję z powrotem do oryginalnego złożonego obiektu ze spłaszczonego słownika EntityProperty. Wszystko, co klient musi zrobić, to powiedzieć API, mam ten Słownik EntityProperty, który właśnie przeczytałem z Tabeli Azure (w formie DynamicTableEntity.Properties), czy możesz przekonwertować go na obiekt tego konkretnego typu. Interfejs API ponownie skompiluje pełny obiekt złożony ze wszystkimi jego właściwościami, w tym właściwości "Wylicz" z ich oryginalnymi prawidłowymi wartościami.

Całe to spłaszczanie i ponowne kompilowanie oryginalnego obiektu odbywa się w sposób przezroczysty dla klienta (użytkownika interfejsu API). Klient nie musi dostarczać żadnego schematu ani żadnej wiedzy do API ObjectFlattenerRecomposer na temat złożonego obiektu, który chce napisać, po prostu przekazuje obiekt do interfejsu API jako "obiekt" w celu spłaszczenia go. Podczas konwersji z powrotem, klient musi jedynie podać rzeczywisty typ obiektu, do którego ma zostać przekonwertowany spłaszczony słownik w formacie EntityProperty. Ogólna metoda ConvertBack interfejsu API po prostu ponownie skompiluje oryginalny obiekt typu T i zwróci go klientowi.

Zobacz przykład zastosowania poniżej. Obiekty nie muszą implementować żadnego interfejsu, takiego jak "ITableEntity", ani dziedziczyć z konkretnej klasy bazowej. Nie muszą udostępniać specjalnego zestawu konstruktorów.

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

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

Zastosowanie:

//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);