2017-02-15 6 views
0

У меня есть таблица Azure, где я вставил гетерогенные объекты. После извлечения я хочу преобразовать их в определенный тип, используя «как». Я пытался это сделать, но он бросил следующую ошибку:не может использовать «как» ключевое слово в DynamicTableEntity (Azure Table)

Cannot be able to convert DynamicTableEntity to TestingEntity Via reference conversion, boxing conversion, unboxing conversion, wrapping conversion or null type conversion.

Есть ли способ я могу преобразовать мои сущности к определенному типу?

Мой код выглядит следующим образом:

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString")); 
       // Create the table client. 
       CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); 

       CloudTable table = tableClient.GetTableReference("TestingWithTableDatetime"); 
       // Create the table if it doesn't exist. 
       table.CreateIfNotExists(); 
    TableQuery<DynamicTableEntity> entityQuery = 
        new TableQuery<DynamicTableEntity>(); 
       var employees = table.ExecuteQuery(entityQuery); 

       IEnumerable<DynamicTableEntity> entities = table.ExecuteQuery(entityQuery); 
       foreach (var e in entities) 
       { 
        EntityProperty entityTypeProperty; 
        if (e.Properties.TryGetValue("EntityType", out entityTypeProperty)) 
        { 
         if (entityTypeProperty.StringValue == "SampleEntity1") 
         { 
//Cannot be able to Use as 
          var TestingWithTableDatetime = e as SampleEntity1; 
         } 
         if (entityTypeProperty.StringValue == "SampleEntity2") 
         { 
          // Use entityTypeProperty, RowKey, PartitionKey, Etag, and Timestamp 
         } 
         if (entityTypeProperty.StringValue == "SampleEntity3") 
         { 
          // Use entityTypeProperty, RowKey, PartitionKey, Etag, and Timestamp 
         } 
        } 
       } 

определение класса для sample1

public class Sample1 : TableEntity 
    { 
     public Sample1(string pk, string rk) 
     { 
      this.PartitionKey = pk; 
      this.RowKey = rk; 
      EntityType = "MonitoringResources"; 
     } 

     public string EntityType { get; set; } 

     public Sample1() 
     { 
     } 


    } 

вещи, которые я tried.I создали класс в качестве тестирования и в том, что я унаследовал Таблица entity.Then Тестирование наследуется sample1, как следовать определению

Тестирование класса

public class testing : TableEntity 
    { 
     public testing(string pk, string rk) 
     { 
      this.PartitionKey = pk; 
      this.RowKey = rk; //MetricKey 
     } 

     public string EntityType { get; set; } 

     public testing() 
     { 
     } 
    } 

модифицированный sample1 Класс:

public class sample1 : testing 
    { 
     public sample1(string pk, string rk) : base(pk, rk) 
     { 
      EntityType = "sample1"; 
     } 

     public sample1() 
     { 
     } 
    } 

В этом я не получил какую-либо ошибку, но когда я преобразуя его в sample1 с помощью «как» он возвращается в нулевое.

Наконец-то я закончил создание помощника.

public static class AzureManager 
    { 
     /// <summary> 
     /// Converts a dynamic table entity to .NET Object 
     /// </summary> 
     /// <typeparam name="TOutput">Desired Object Type</typeparam> 
     /// <param name="entity">Dynamic table Entity</param> 
     /// <returns>Output Object</returns> 
     public static TOutput ConvertTo<TOutput>(DynamicTableEntity entity) 
     { 
      return ConvertTo<TOutput>(entity.Properties, entity.PartitionKey, entity.RowKey); 
     } 

     /// <summary> 
     /// Convert a Dynamic Table Entity to A POCO .NET Object. 
     /// </summary> 
     /// <typeparam name="TOutput">Desired Object Types</typeparam> 
     /// <param name="properties">Dictionary of Table Entity</param> 
     /// <returns>.NET object</returns> 
     public static TOutput ConvertTo<TOutput>(IDictionary<string, EntityProperty> properties, string partitionKey, string rowKey) 
     { 
      var jobject = new JObject(); 
      properties.Add("PartitionKey", new EntityProperty(partitionKey)); 
      properties.Add("RowKey", new EntityProperty(rowKey)); 
      foreach (var property in properties) 
      { 
       WriteToJObject(jobject, property); 
      } 
      return jobject.ToObject<TOutput>(); 
     } 

     public static void WriteToJObject(JObject jObject, KeyValuePair<string, EntityProperty> property) 
     { 
      switch (property.Value.PropertyType) 
      { 
       case EdmType.Binary: 
        jObject.Add(property.Key, new JValue(property.Value.BinaryValue)); 
        return; 

       case EdmType.Boolean: 
        jObject.Add(property.Key, new JValue(property.Value.BooleanValue)); 
        return; 

       case EdmType.DateTime: 
        jObject.Add(property.Key, new JValue(property.Value.DateTime)); 
        return; 

       case EdmType.Double: 
        jObject.Add(property.Key, new JValue(property.Value.DoubleValue)); 
        return; 

       case EdmType.Guid: 
        jObject.Add(property.Key, new JValue(property.Value.GuidValue)); 
        return; 

       case EdmType.Int32: 
        jObject.Add(property.Key, new JValue(property.Value.Int32Value)); 
        return; 

       case EdmType.Int64: 
        jObject.Add(property.Key, new JValue(property.Value.Int64Value)); 
        return; 

       case EdmType.String: 
        jObject.Add(property.Key, new JValue(property.Value.StringValue)); 
        return; 

       default: 
        return; 
      } 
     } 
    } 

вышеуказанный работает для меня.

var obj= AzureManager.ConvertTo<Sample1>(e); 

Если вы найдете какой-либо другой способ.

+0

Вы можете разместить определение класса 'SampleEntity1', например? –

+0

Просто предположение, вместо того, чтобы идти вперед с 'DynamicTableEntity', пытается переопределить методы WriteEntity()' и 'ReadEntity()'. Вы получите похожие результаты, и запрос будет намного проще. И, как было предложено @PeterBons, отредактируйте свой вопрос и предоставите 'SampleEntity1'. – Sameer

+1

Если вы хотите придерживаться 'DynamicTableEntity', перейдите по ссылке (https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-tables). В одном из разделов объясняется, как ** Запросить подмножество свойств сущности **. – Sameer

ответ

0

Is there any way I can convert my entities to a particular type?

Мы могли бы использовать DynamicTableEntityConverter для этого.

В соответствии с вашим кодом, мы могли бы использовать следующий код для преобразования DynamicTableEntity в Sample1

var TestingWithTableDatetime = DynamicTableEntityConverter.ConvertToPOCO<Sample1>(e); 
+0

Я попробовал DynamicTableEntityConverter.ConvertToPOCO (e); но я получаю нулевое значение в ключе раздела, а также в строке. – Skull

0

Вот альтернативный и гораздо более простое решение для вас, что изначально поддерживается Azure Storage SDK версии> 8.0.0 , Вам даже не нужно писать код преобразования/преобразования :)

взглянуть на: метод

TableEntity.Flatten: метод https://msdn.microsoft.com/en-us/library/azure/mt775434.aspx

TableEntity.ConvertBack: https://msdn.microsoft.com/en-us/library/azure/mt775432.aspx

Эти методы являются предоставляемые SDK как статические, автономные вспомогательные методы. Метод Flatten преобразует ваши объекты в плоский словарь свойств сущностей, где вы можете просто назначить ключ раздела и ключ строки, создать динамичность из плоского словаря и записать в хранилище таблиц azure.

Если вы хотите прочитать объект назад, прочитайте его как объект динамической таблицы и передайте словарь свойств возвращаемого объекта динамической таблицы методу TableEntity.ConvertBack.Просто скажите, какой тип объекта вы хотите, чтобы метод конвертировал словарь свойств в его общий параметр типа, и он выполнит преобразование для вас.

Первоначально я реализовал эти api как пакеты nuget, и теперь они интегрированы в azure storage sdk. Если вы хотите, чтобы прочитать немного больше о том, как они работают, вы можете увидеть статью, которую я написал первоначально о NuGet пакетах здесь:

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