Windows Azure入门教学系列 (六):使用Table Storage

简介: 本文是Windows Azure入门教学的第六篇文章。 本文将会介绍如何使用Table Storage。Table Storage提供给我们一个云端的表格结构。我们可以把他想象为XML文件或者是一个轻量级的数据库(当然,不是通过SQL 语句进行数据的操作)。

本文是Windows Azure入门教学的第六篇文章。

本文将会介绍如何使用Table Storage。Table Storage提供给我们一个云端的表格结构。我们可以把他想象为XML文件或者是一个轻量级的数据库(当然,不是通过SQL 语句进行数据的操作)。

使用Table Storage的方法依然是调用REST API。有关Table Storage REST API的详细信息,请参见Table服务API:

为了方便.NET开发人员,我们在SDK中提供了Microsoft.WindowsAzure.StorageClient类来帮助发送REST请求。

在开始本教学之前,请确保你从Windows Azure 平台下载下载并安装了最新的Windows Azure开发工具。本教学使用Visual Studio 2010作为开发工具。

步骤一:创建解决方案和项目

由于我们要在本地模拟环境下测试Table Storage,首先,请确保Storage Emulator已经启动。我们可以找到管理器的进程手动启动或者让Visual Studio 2010帮助我们启动他。

右击工具栏中Windows Azure模拟器的图标,选择”Show Storage Emulator UI”。弹出如下图所示的窗口:

我们要关注的是Service management中Table所在的一行。要确保Status为Running。

确认完毕后启动Visual Studio 2010,并且新建一个Console项目。

步骤二:添加程序集引用

请在项目属性页里确认项目的Target framework的值是.NET Framework 4或.NET Framework 3.5。然后添加对C:Program FilesWindows Azure SDKv1.3refMicrosoft.WindowsAzure.StorageClient.dll的引用。该路径为SDK默认安装路径,如果你不能在这个路径中找到Microsoft.WindowsAzure.StorageClient.dll请从SDK安装路径中寻找。

接下来添加对System.Data.Services.Client程序集的引用。该程序集安装在GAC中。你能够在Add Reference窗口的.NET标签下找到他。

步骤三:添加代码

首先在项目中的Program.cs中引用命名空间:

 

1
2
3
using Microsoft.WindowsAzure;
 
using Microsoft.WindowsAzure.StorageClient;

然后在Program.cs中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
class Program
 
{
 
     static void Main(string[] args)
 
     {
 
         var storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
 
         var tableStorage = storageAccount.CreateCloudTableClient();
 
  
 
         // 检查名为CustomerInfo的表格是否被创建,如果没有,创建它
 
         tableStorage.CreateTableIfNotExist("CustomerInfo");
 
  
 
         // 创建表格服务上下文
 
         var context = new CustomerInfoContext(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
 
  
 
         // 插入两条客户信息数据,客户ID分别设置为0和1
 
         CustomerInfo ci1 = new CustomerInfo() { CustomerAge = 25, CustomerID = "0", CustomerName = "Mike" };
 
         context.AddObject("CustomerInfo", ci1);
 
  
 
         CustomerInfo ci2 = new CustomerInfo() { CustomerAge = 32, CustomerID = "1", CustomerName = "Peter" };
 
         context.AddObject("CustomerInfo", ci2);
 
  
 
         context.SaveChanges();
 
  
 
  
 
         // 查找CustomerID为1的客户数据并显示
 
  
 
         Console.WriteLine("Retrieve information of a customer whose ID is 1");
 
  
 
         var query = context.CreateQuery< CustomerInfo >("CustomerInfo").Where(c => c.CustomerID == "1").ToList();
 
         var returnedcustomerinfo = query.FirstOrDefault();
 
  
 
         Console.WriteLine(string.Format("Customer info retrieved: ID:{0},Name:{1},Age:{2}",
 
             returnedcustomerinfo.CustomerID, returnedcustomerinfo.CustomerName, returnedcustomerinfo.CustomerAge));
 
  
 
  
 
         // 更新CustomerID为1的客户数据中的年龄
 
         returnedcustomerinfo.CustomerAge = 33;
 
         context.UpdateObject(returnedcustomerinfo);
 
         Console.WriteLine("**Customer Info updated**");
 
  
 
         // 重新查询,测试更新效果
 
  
 
         Console.WriteLine("Retrieve information of a customer whose ID is 1");
 
  
 
         var query2 = context.CreateQuery< CustomerInfo >("CustomerInfo").Where(c => c.CustomerID == "1").ToList();
 
         var returnedcustomerinfo2 = query.FirstOrDefault();
 
         Console.WriteLine(string.Format("Customer info retrieved: ID:{0},Name:{1},Age:{2}",
 
                 returnedcustomerinfo2.CustomerID, returnedcustomerinfo2.CustomerName, returnedcustomerinfo2.CustomerAge));
 
  
 
  
 
         // 删除插入的两条客户数据
 
         context.DeleteObject(ci1);
 
         context.DeleteObject(ci2);
 
         context.SaveChanges();
 
  
 
         Console.WriteLine("The records has been deleted");
 
         Console.ReadLine();
 
     }
 
  
 
}
 
public class CustomerInfo : TableServiceEntity
 
{
 
     public string CustomerID
 
     {
 
         get { return this.RowKey; }
 
         set { this.RowKey = value; }
 
     }
 
     public string CustomerName { get; set; }
 
     public int CustomerAge { get; set; }
 
  
 
     public CustomerInfo()
 
     {
 
         this.PartitionKey = "mypartitionkey";
 
     }
 
}
 
  
 
public class CustomerInfoContext : TableServiceContext
 
{
 
     public CustomerInfoContext(string baseAddress, StorageCredentials credentials) :
 
         base(baseAddress, credentials)
 
     {
 
     }
 
}

步骤四:观察并分析代码

步骤三中的代码中,首先我们通过CloudStorageAccount.DevelopmentStorageAccount来说明我们使用的本地的Development Storage自带账户而不是真正的云端存储服务账户。(如果要用真实账户可以使用

//DefaultEndpointsProtocol=https可以改成DefaultEndpointsProtocol=http表示用HTTP而不是HTTPS

CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=[用户名];AccountKey=[密码]");

来实例化对象)然后通过该账户类来实例化一个Table客户端类。这两步是使用SDK中StorageClient程序集来调用Table Storage服务的必要步骤。

然后我们需要关注System.Data.Services.Client程序集。该程序集是WCF Data Services的客户端程序集,能够帮助我们很方便地创建OData客户端程序。(Table Storage提供的REST API遵循OData规范,因此我们的客户端需要遵循OData规范向Table Storage服务发送消息)

我们需要创建上下文来调用服务,我们可以直接使用TableServiceContext。但是通常我们会通过写一个继承自TableServiceContext的类来实现,这样我们可以在该类中添加一些属性或者方法来更加方便地调用。上面的代码中我们继承了TableServiceContext但是并没有添加额外的代码。在实际应用中我们可以加上一些代码来更加方便地调用。比如我们可以在CustomerInfoContext 类中加入下面的属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
public IQueryable< CustomerInfo > CustomerInfo
 
{
 
     get
 
     {
 
         return CreateQuery< CustomerInfo >("CustomerInfo");
 
     }
 
}

这样我们就可以通过调用context.CustomerInfo来更加代替context.CreateQuery<CustomerInfo>("CustomerInfo")。

继承自TableServiceEntity类的CustomerInfo 类定义了每条数据的模式。需要注意的是,与一般的关系型数据库不同,Table Storage并不要求一个表中的所有数据都遵循同一模式。举例来说,在一个表中,可以存储一条有三个字段的记录和一条只有两个字段的记录。这也是我们为什么说可以把Table Storage想象为XML文件的原因。当然在通常情况下我们都会需要在一个表中存储同一模式的数据。这时候我们就可以使用System.Data.Services.Client程序集来为Table Storage创建客户端程序。当我们需要在一个表中存储不同模式的数据时我们可以手动构建和发送REST请求。

还有需要注意的地方是PartitionKey和RowKey。这两项共同组合成表的主键。详细信息,请参见理解Table服务数据模型

代码逻辑包括了对Table Storage的插入,更新,删除和读取。请参考注释部分。

步骤五:运行程序

如果一切正常,你将会看到Console程序输出如下信息:         

目录
相关文章
|
2月前
|
Shell Linux 开发工具
Git入门(windows系统)
Git入门(windows系统)
51 1
|
8月前
|
消息中间件 数据安全/隐私保护 网络架构
Windows下RabbitMQ安装及入门
Windows下RabbitMQ安装及入门
|
2月前
|
API C++ Windows
windows编程入门_链接错误的配置
windows编程入门_链接错误的配置
29 0
|
2月前
|
机器人 Linux 数据安全/隐私保护
Python办公自动化【Windows中定时任务、OS/linux 系统定时任务 、Python 钉钉发送消息、Python 钉钉发送图片】(九)-全面详解(学习总结---从入门到深化)
Python办公自动化【Windows中定时任务、OS/linux 系统定时任务 、Python 钉钉发送消息、Python 钉钉发送图片】(九)-全面详解(学习总结---从入门到深化)
130 0
|
2月前
|
机器人 Linux 数据安全/隐私保护
Python办公自动化【Windows中定时任务、OS/linux 系统定时任务 、Python 钉钉发送消息、Python 钉钉发送图片】(九)-全面详解(学习总结---从入门到深化)(下)
Python办公自动化【Windows中定时任务、OS/linux 系统定时任务 、Python 钉钉发送消息、Python 钉钉发送图片】(九)-全面详解(学习总结---从入门到深化)
91 0
|
2月前
|
Linux Python Windows
Python办公自动化【Windows中定时任务、OS/linux 系统定时任务 、Python 钉钉发送消息、Python 钉钉发送图片】(九)-全面详解(学习总结---从入门到深化)(上)
Python办公自动化【Windows中定时任务、OS/linux 系统定时任务 、Python 钉钉发送消息、Python 钉钉发送图片】(九)-全面详解(学习总结---从入门到深化)
58 0
|
2月前
|
SQL Shell 数据库
七天.NET 8操作SQLite入门到实战 - 第二天 在 Windows 上配置 SQLite环境
七天.NET 8操作SQLite入门到实战 - 第二天 在 Windows 上配置 SQLite环境
|
2月前
|
监控 API C++
8.4 Windows驱动开发:文件微过滤驱动入门
MiniFilter 微过滤驱动是相对于`SFilter`传统过滤驱动而言的,传统文件过滤驱动相对来说较为复杂,且接口不清晰并不符合快速开发的需求,为了解决复杂的开发问题,微过滤驱动就此诞生,微过滤驱动在编写时更简单,多数`IRP`操作都由过滤管理器`(FilterManager或Fltmgr)`所接管,因为有了兼容层,所以在开发中不需要考虑底层`IRP`如何派发,更无需要考虑兼容性问题,用户只需要编写对应的回调函数处理请求即可,这极大的提高了文件过滤驱动的开发效率。
62 0
|
11月前
|
API C++ Windows
Windows入门篇一之MSDN手册的使用和第一个窗口程序
Windows入门篇一之MSDN手册的使用和第一个窗口程序
Windows入门篇一之MSDN手册的使用和第一个窗口程序
|
Dart 前端开发 Java
用Jetpack Compose Desktop极简配置做一个Windows桌面时间显示器(compose框架入门向)
compose的模板配置多少有些臃肿,如果只做单一平台多少是会简单一些的。但几乎没怎么见过配置很简单的例子,都是套那些模板,我觉得没必要搞那么复杂,那么本文就做一个非常简单的只有几行代码的小例子
1149 0
用Jetpack Compose Desktop极简配置做一个Windows桌面时间显示器(compose框架入门向)