无法在DynamicTableEntity(Azure表)

时间:2017-02-15 10:06:03

标签: azure azure-table-storage

我有一个Azure表,我在其中插入了异构实体。检索后,我想使用“as”将它们转换为某种特定类型。我试图这样做,但它引发了以下错误:

  

无法将DynamicTableEntity转换为TestingEntity通过引用转换,装箱转换,取消装箱转换,换行转换或空类型转换。

我有什么方法可以将我的实体转换为特定类型吗?

我的代码如下:

 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()
        {
        }


    }

我尝试过的东西。我创建了一个类作为Testing,并且我继承了Table实体。然后,sample1继承了test,如下所示

测试类定义

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

        public string EntityType { get; set; }

        public testing()
        {
        }
    }

修改过的Class sample1:

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

        public sample1()
        {
        }
    }

在这里我没有得到任何错误但是 当我使用“as”将其转换为sample1时,它返回为null。

最后,我结束了创建一些帮手。

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

如果您发现任何其他方式。请建议。

2 个答案:

答案 0 :(得分:3)

以下是Azure Storage SDK版本&gt;本机支持的另一种更简单的解决方案。 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/

答案 1 :(得分:0)

  

我有什么方法可以将我的实体转换为特定类型吗?

我们可以使用DynamicTableEntityConverter来做到这一点。

根据您的代码,我们可以使用以下代码将DynamicTableEntity转换为Sample1

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