azure - 无法在 DynamicTableEntity(Azure 表)中使用 "as"关键字

标签 azure azure-table-storage

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

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


    }

我尝试过的事情。我创建了一个类作为测试,并在其中继承了表实体。然后测试由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()
        {
        }
    }

修改后的类示例1:

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

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

最佳答案

这里为您提供了一种更简单的替代解决方案,Azure 存储 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/

关于azure - 无法在 DynamicTableEntity(Azure 表)中使用 "as"关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42246213/

相关文章:

java - 运行 Spring Boot Azure Function App 时出错

azure - Windows Azure 表服务 - 扩展属性和表架构

json - Azure 表存储 JSON 返回每个条目的数组而不是单个数组

c# - async wait 使我的任务变慢,而 task.Start() 运行速度很快

azure - 如何在 Windows Azure 管理门户中查看 .svclogs

azure - NLog 与 AzureTableStorage

c# - Azure Active Directory 使用错误的应用程序客户端 ID

azure - 记录来自 Azure 事件中心的所有消息的最简单方法

sql-server - 错误: SQL71564 When migrating to Azure

azure - 使用 Bicep 创建 Azure 资源组