ITPub博客

首页 > 数据库 > > Azure Table storage 之改进DynamicTableEntity类

Azure Table storage 之改进DynamicTableEntity类

作者:LCR_ 时间:2022-04-24 18:01:17 0 删除 编辑

在之前的一篇文章中提到,storage类库中包含一个可以用来动态获取Azure table storage 表结构的类-DynamicTableEntity。

我们可以通过这个类,我们无需为每一个表提前声明一个class,也能够对其进行操作。

但在我们要添加Entity到表中的时候会感觉到一点不舒服

以下我所希望使用的该类的方式:

  1. dynamic entity = new DynamicTableEntity();
  2. entity.Name=”sam”;
  3. entity.Gender=true;
  4. …

这样的形式

而实际代码却是

  1. DynamicTableEntity entity1 = new DynamicTableEntity();
  2. Dictionary<string, EntityProperty> data1 = new Dictionary<string, EntityProperty>();
  3. data1.Add("Name", new EntityProperty("Sam"));
  4. data1.Add("Gender", new EntityProperty(true));
  5. data1.Add("Age", new EntityProperty(18));
  6. entity1.Properties = data1;
  7. entity1.PartitionKey = "Partition1";
  8. entity1.RowKey = "1";
  9. UserDataList.Add(entity1);

  

身为一个以dynamic开头的类居然不能够用dynamic关键字来初始化它,在实例化一个DynamicTableEntity类的时候居然要如此麻烦,实在让人不爽。

所以, 经过一番研究,发现了一个可以支持动态扩展的类,为了与DynamicTableEntity区分开来,所以取名DynamicObjectTableEntity。它实现了DynamicTableEntity相同的功能,而且继承了DynamicObject,从而具有动态语言的特性,更加方便 使用。

而且动态语言扩展一直以来除了在linq中使用比较多以外,其它地方基本看不到。这里正好通过对dynamicTableEntity的改造可以加深对动态语言扩展的理解。

实现代码如下:

  1. public class DynamicObjectTableEntity : DynamicObject,ITableEntity
  2. {
  3. #region DynamicTableEntity's code
  4. // Methods
  5. public DynamicObjectTableEntity()
  6. {
  7. this.Properties = new Dictionary<string, EntityProperty>();
  8. }
  9. public DynamicObjectTableEntity(string partitionKey, string rowKey) : this(partitionKey, rowKey, DateTimeOffset.MinValue, null, new Dictionary<string, EntityProperty>())
  10. {
  11. }
  12. public DynamicObjectTableEntity(string partitionKey, string rowKey, string etag, IDictionary<string, EntityProperty> properties) : this(partitionKey, rowKey, DateTimeOffset.MinValue, etag, properties)
  13. {
  14. }
  15. internal DynamicObjectTableEntity(string partitionKey, string rowKey, DateTimeOffset timestamp, string etag, IDictionary<string, EntityProperty> properties)
  16. {
  17. //CommonUtility.AssertNotNull("partitionKey", partitionKey);
  18. //CommonUtility.AssertNotNull("rowKey", rowKey);
  19. //CommonUtility.AssertNotNull("properties", properties);
  20. this.PartitionKey = partitionKey;
  21. this.RowKey = rowKey;
  22. this.Timestamp = timestamp;
  23. this.ETag = etag;
  24. this.Properties = properties;
  25. }
  26. public void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext)
  27. {
  28. this.Properties = properties;
  29. }
  30. public IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext)
  31. {
  32. return this.Properties;
  33. }
  34. // Properties
  35. public string ETag { get; set; }
  36. public EntityProperty this[string key]
  37. {
  38. get
  39. {
  40. return this.Properties[key];
  41. }
  42. set
  43. {
  44. this.Properties[key] = value;
  45. }
  46. }
  47. public string PartitionKey { get; set; }
  48. public IDictionary<string, EntityProperty> Properties { get; set; }
  49. public string RowKey { get; set; }
  50. public DateTimeOffset Timestamp { get; set; }
  51. #endregion
  52. #region override DynamicObject's mehtods
  53. public override bool TryGetMember(GetMemberBinder binder, out object result)
  54. {
  55. if (!Properties.ContainsKey(binder.Name))
  56. Properties.Add(binder.Name, ConvertToEntityProperty(binder.Name, null));
  57. result = Properties[binder.Name];
  58. return true;
  59. }
  60. public override bool TrySetMember(SetMemberBinder binder, object value)
  61. {
  62. EntityProperty property = ConvertToEntityProperty(binder.Name, value);
  63. if (Properties.ContainsKey(binder.Name))
  64. Properties[binder.Name] = property;
  65. else
  66. Properties.Add(binder.Name, property);
  67. return true;
  68. }
  69. /// <summary>
  70. /// Convert object value to EntityProperty.
  71. /// </summary>
  72. private EntityProperty ConvertToEntityProperty(string key, object value)
  73. {
  74. if (value == null) return new EntityProperty((string)null);
  75. if (value.GetType() == typeof(byte[]))
  76. return new EntityProperty((byte[])value);
  77. if (value.GetType() == typeof(bool))
  78. return new EntityProperty((bool)value);
  79. if (value.GetType() == typeof(DateTimeOffset))
  80. return new EntityProperty((DateTimeOffset)value);
  81. if (value.GetType() == typeof(DateTime))
  82. return new EntityProperty((DateTime)value);
  83. if (value.GetType() == typeof(double))
  84. return new EntityProperty((double)value);
  85. if (value.GetType() == typeof(Guid))
  86. return new EntityProperty((Guid)value);
  87. if (value.GetType() == typeof(int))
  88. return new EntityProperty((int)value);
  89. if (value.GetType() == typeof(long))
  90. return new EntityProperty((long)value);
  91. if (value.GetType() == typeof(string))
  92. return new EntityProperty((string)value);
  93. throw new Exception("This value type" + value.GetType() + " for " + key);
  94. throw new Exception(string.Format("This value type {0} is not supported for {1}", key));
  95. }
  96. /// <summary>
  97. /// Get the edm type, if the type is not a edm type throw a exception.
  98. /// </summary>
  99. private Type GetType(EdmType edmType)
  100. {
  101. switch (edmType)
  102. {
  103. case EdmType.Binary:
  104. return typeof(byte[]);
  105. case EdmType.Boolean:
  106. return typeof(bool);
  107. case EdmType.DateTime:
  108. return typeof(DateTime);
  109. case EdmType.Double:
  110. return typeof(double);
  111. case EdmType.Guid:
  112. return typeof(Guid);
  113. case EdmType.Int32:
  114. return typeof(int);
  115. case EdmType.Int64:
  116. return typeof(long);
  117. case EdmType.String:
  118. return typeof(string);
  119. default: throw new TypeLoadException(string.Format("not supported edmType:{0}", edmType));
  120. }
  121. }
  122. #endregion
  123. }

 

在使用了如下类之后,我们就可以用我预期的代码来操作table 了

代码如下:

  1. static void Main(string[] args)
  2. {
  3. var connectionString = "DefaultEndpointsProtocol=https;AccountName=[Account];AccountKey=[Key]";
  4. CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
  5. try
  6. {
  7. var client = storageAccount.CreateCloudTableClient();
  8. var table = client.GetTableReference("ShortMessages");
  9. table.CreateIfNotExists();
  10. dynamic entity = new DynamicObjectTableEntity("default", DateTime.Now.ToShortTimeString());
  11. entity.Name = "pete";
  12. entity.Message = "Hello";
  13. table.Execute(TableOperation.Insert(entity));
  14. Console.WriteLine("insert successfully!");
  15. }
  16. catch (Exception ex)
  17. {
  18. Console.WriteLine(ex.Message);
  19. }
  20. Console.Read();
  21. }

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70000523/viewspace-3168052/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2022-02-22

  • 博文量
    1402
  • 访问量
    15049