Azure Table storage 之改进DynamicTableEntity类为其添加动态语言扩展
在之前的一篇文章中提到,storage类库中包含一个可以用来动态获取Azure table storage 表结构的类-DynamicTableEntity。
我们可以通过这个类,我们无需为每一个表提前声明一个class,也能够对其进行操作。
但在我们要添加Entity到表中的时候会感觉到一点不舒服
以下我所希望使用的该类的方式:
dynamic entity = new DynamicTableEntity();
entity.Name=”sam”;
entity.Gender=true;
…
这样的形式
而实际代码却是
DynamicTableEntity entity1 = new DynamicTableEntity();
Dictionary<string, EntityProperty> data1 = new Dictionary<string, EntityProperty>();
data1.Add("Name", new EntityProperty("Sam"));
data1.Add("Gender", new EntityProperty(true));
data1.Add("Age", new EntityProperty(18));
entity1.Properties = data1;
entity1.PartitionKey = "Partition1";
entity1.RowKey = "1";
UserDataList.Add(entity1);
身为一个以dynamic开头的类居然不能够用dynamic关键字来初始化它,在实例化一个DynamicTableEntity类的时候居然要如此麻烦,实在让人不爽。
所以, 经过一番研究,发现了一个可以支持动态扩展的类,为了与DynamicTableEntity区分开来,所以取名DynamicObjectTableEntity。它实现了DynamicTableEntity相同的功能,而且继承了DynamicObject,从而具有动态语言的特性,更加方便 使用。
而且动态语言扩展一直以来除了在linq中使用比较多以外,其它地方基本看不到。这里正好通过对dynamicTableEntity的改造可以加深对动态语言扩展的理解。
实现代码如下:
public class DynamicObjectTableEntity : DynamicObject,ITableEntity
{
#region DynamicTableEntity's code
// Methods
public DynamicObjectTableEntity()
{
this.Properties = new Dictionary<string, EntityProperty>();
} public DynamicObjectTableEntity(string partitionKey, string rowKey) : this(partitionKey, rowKey, DateTimeOffset.MinValue, null, new Dictionary<string, EntityProperty>())
{
} public DynamicObjectTableEntity(string partitionKey, string rowKey, string etag, IDictionary<string, EntityProperty> properties) : this(partitionKey, rowKey, DateTimeOffset.MinValue, etag, properties)
{
} internal DynamicObjectTableEntity(string partitionKey, string rowKey, DateTimeOffset timestamp, string etag, IDictionary<string, EntityProperty> properties)
{
//CommonUtility.AssertNotNull("partitionKey", partitionKey);
//CommonUtility.AssertNotNull("rowKey", rowKey);
//CommonUtility.AssertNotNull("properties", properties);
this.PartitionKey = partitionKey;
this.RowKey = rowKey;
this.Timestamp = timestamp;
this.ETag = etag;
this.Properties = properties;
} public void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext)
{
this.Properties = properties;
} public IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext)
{
return this.Properties;
} // Properties
public string ETag { get; set; } public EntityProperty this[string key]
{
get
{
return this.Properties[key];
}
set
{
this.Properties[key] = value;
}
} public string PartitionKey { get; set; } public IDictionary<string, EntityProperty> Properties { get; set; } public string RowKey { get; set; } public DateTimeOffset Timestamp { get; set; } #endregion #region override DynamicObject's mehtods
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (!Properties.ContainsKey(binder.Name))
Properties.Add(binder.Name, ConvertToEntityProperty(binder.Name, null));
result = Properties[binder.Name];
return true;
} public override bool TrySetMember(SetMemberBinder binder, object value)
{
EntityProperty property = ConvertToEntityProperty(binder.Name, value); if (Properties.ContainsKey(binder.Name))
Properties[binder.Name] = property;
else
Properties.Add(binder.Name, property); return true;
} /// <summary>
/// Convert object value to EntityProperty.
/// </summary>
private EntityProperty ConvertToEntityProperty(string key, object value)
{
if (value == null) return new EntityProperty((string)null);
if (value.GetType() == typeof(byte[]))
return new EntityProperty((byte[])value);
if (value.GetType() == typeof(bool))
return new EntityProperty((bool)value);
if (value.GetType() == typeof(DateTimeOffset))
return new EntityProperty((DateTimeOffset)value);
if (value.GetType() == typeof(DateTime))
return new EntityProperty((DateTime)value);
if (value.GetType() == typeof(double))
return new EntityProperty((double)value);
if (value.GetType() == typeof(Guid))
return new EntityProperty((Guid)value);
if (value.GetType() == typeof(int))
return new EntityProperty((int)value);
if (value.GetType() == typeof(long))
return new EntityProperty((long)value);
if (value.GetType() == typeof(string))
return new EntityProperty((string)value);
throw new Exception("This value type" + value.GetType() + " for " + key);
throw new Exception(string.Format("This value type {0} is not supported for {1}", key));
} /// <summary>
/// Get the edm type, if the type is not a edm type throw a exception.
/// </summary>
private Type GetType(EdmType edmType)
{
switch (edmType)
{
case EdmType.Binary:
return typeof(byte[]);
case EdmType.Boolean:
return typeof(bool);
case EdmType.DateTime:
return typeof(DateTime);
case EdmType.Double:
return typeof(double);
case EdmType.Guid:
return typeof(Guid);
case EdmType.Int32:
return typeof(int);
case EdmType.Int64:
return typeof(long);
case EdmType.String:
return typeof(string);
default: throw new TypeLoadException(string.Format("not supported edmType:{0}", edmType));
}
} #endregion
}
在使用了如下类之后,我们就可以用我预期的代码来操作table 了
代码如下:
static void Main(string[] args)
{
var connectionString = "DefaultEndpointsProtocol=https;AccountName=[Account];AccountKey=[Key]";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
try
{
var client = storageAccount.CreateCloudTableClient();
var table = client.GetTableReference("ShortMessages");
table.CreateIfNotExists();
dynamic entity = new DynamicObjectTableEntity("default", DateTime.Now.ToShortTimeString()); entity.Name = "pete";
entity.Message = "Hello";
table.Execute(TableOperation.Insert(entity));
Console.WriteLine("insert successfully!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}
示例参考MSDN:http://code.msdn.microsoft.com/Dynamic-TableServiceEntity-151d661f
Azure Table storage 之改进DynamicTableEntity类为其添加动态语言扩展的更多相关文章
- Windows Azure Table storage 之 动态Table类 DynamicTableEntity
在一般情况下,当我们在.net中使用Azure table storage的时候都会为该表建立一个TableEntity的派生类,如下所示. public class CustomerEntity : ...
- Azure Table storage 基本用法 -- Azure Storage 之 Table
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table,其中的 Table 就是本文的主角 Azure Tabl ...
- 自定义 Azure Table storage 查询过滤条件
本文是在Azure Table storage 基本用法一文的基础上,介绍如何自定义 Azure Table storage 的查询过滤条件.如果您还不太清楚 Azure Table storage ...
- Windows Azure Table Storage 解决 Guid 查询问题
在使用 Windows Azure Table Storage 的 CloudTableClient 对Azure 进行数据查询时,会发现在自定义类的Guid类型始终无法去成功查询出数据,对比发现 G ...
- Azure Table Storage(一) : 简单介绍
Azure Table Storage是什么: Azure Table Storage是隶属于微软Azure Storage这个大服务下的一个子服务, 这个服务在Azure上算是老字号了, 个人大概在 ...
- Azure 基础:Table storage
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table.其中的 Table 就是本文的主角 Azure Tabl ...
- Azure 基础:自定义 Table storage 查询条件
本文是在 <Azure 基础:Table storage> 一文的基础上介绍如何自定义 Azure Table storage 的查询过滤条件.如果您还不太清楚 Azure Table s ...
- [Windows Azure] How to use the Table Storage Service
How to use the Table Storage Service version 1.7 version 2.0 This guide will show you how to perform ...
- Azure Storage 系列(四)在.Net 上使用Table Storage
一,引言 今天我们就不多说废话了,直接进入正题,Azure Table Storage.开始内容之前,我们先介绍一下Azure Table Storage. 1,什么是Azure Table Stor ...
随机推荐
- 去掉tppabs冗余代码,怎样批量去掉tppabs代码
去掉tppabs冗余代码,怎样批量去掉tppabs代码 刚用teleport pro拉了一个整站到本地 所有的超链都被强行加了一句tppabs=" 就玩了一把dw的替换功能 查找范围:整 ...
- 【BUG】wego购物分享系统未登陆分享宝贝时查看宝贝自动新增产品数据
1.登录微购http://demo.wego360.com/站. 2.分享宝贝功能检索第三方平台商品数据. 1.登录微购http://demo.wego360.com/站. 2.分享宝贝功能检索第三方 ...
- servlet session 相关
1.session是server维护的一个变量,如果消除每个session?----这里只做指定key的session删除 1.1.显示调用 废除指定key的session session.remov ...
- [转载]学习VC MFC开发必须了解的常用宏和指令————复习一下
1.#include指令 包含指定的文件 2.#define指令 预定义,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善.背后一长串”的宏,它本身并不在编译过程中进行,而 ...
- hdu Is It A Tree?
判定给定的边序列是否过程一棵树.我用到的判定方法是:第一步:判定 边数是否等于顶点数-1 第二:判定是否只有一个根节点 .当然还要考虑是否为空树的情况. 但是代码交上去,好几遍都是Runtime ...
- web实验指导书和课后习题参考答案
实验指导书 :http://course.baidu.com/view/daf55bd026fff705cc170add.html 课后习题参考答案:http://wenku.baidu.com/li ...
- svn版本升级遇到的bug
从svn1.0升级到svn10.x时发生的bug 1.可能是没有javahl这个架包或是与你升级后的svn版本不匹配,eclipse在线下载就好 2.项目因为之前连接是较低版本的svn,当svn升级后 ...
- java客户端调用c#的webservice服务
此处使用到了CXF框架,可以使用以下坐标从maven仓库中获取相关jar包: <dependency> <groupId>org.apache.cxf</groupId& ...
- IOS第七天(4:UiTableView 数据的显示优化重复实例和tableFooterView和tableHeaderView)
//加上头部 和底部 - (void)viewDidLoad { [super viewDidLoad]; [self tableView]; // 设置行高 self.tableView.rowHe ...
- PHP Header下载文件在IE文件名中文乱码问题
解决PHP Header下载文件在IE文件名中文乱码有两种常见的,一种是是把页面编码改成utf8,另一种是对中文url进入urlencode编码,根据UA检测,区别下载,就可以解决了 $filenam ...