Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96816
  • 博文数量: 50
  • 博客积分: 1424
  • 博客等级: 上尉
  • 技术积分: 430
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-17 09:48
文章分类
文章存档

2010年(50)

我的朋友
最近访客

分类: WINDOWS

2010-05-17 11:15:38

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

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

使用Table Storage的方法依然是调用 API。有关Table Storage API的详细信息可以参考:

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

要继续本教学,请确保自己的机体上安装了最新版的Windows Azure Tools for Microsoft Visual Studio。当前的最新版(20102月)可以从以下站点下载:

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

由于我们要在本地模拟环境下测试Table Storage,首先,请确保Development Storage的管理器程序已经启动。我们可以找到管理器的进程手动启动或者让Visual Studio帮助我们启动他。你可以参考第一篇教学文章来启动他:

http://blogs.msdn.com/azchina/archive/2010/02/09/windows-azure-webrole.aspx

右击工具栏中Development Fabric的图标,选择”Show Development Storage UI”。弹出如下图所示的窗口:

我们要关注的是Service managementTable所在的一行。要确保StatusRunning

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

步骤二:添加程序集引用

Console项目中添加对C:\Program Files\Windows Azure SDK\v1.1\ref\Microsoft.WindowsAzure.StorageClient.dll的引用。该路径为SDK默认安装路径,如果你不能在这个路径中找到Microsoft.WindowsAzure.StorageClient.dll请从SDK安装路径中寻找。

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

步骤三:添加代码

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

using Microsoft.WindowsAzure;

using Microsoft.WindowsAzure.StorageClient;

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

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分别设置为01

            CustomerInfo ci1 = new CustomerInfo() { CustomerAge = 25, CustomerID = "0", CustomerName = "Mike" };

            CustomerInfo ci2 = new CustomerInfo() { CustomerAge = 32, CustomerID = "1", CustomerName = "Peter" };

            context.AddObject("CustomerInfo", ci1);

            context.AddObject("CustomerInfo", ci2);

            context.SaveChanges();

            // 查找CustomerID1的客户数据并显示

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

            // 更新CustomerID1的客户数据中的年龄

            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自带账户而不是真正的云端存储服务账户。(如果要用真实账户可以使用

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

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

实例化对象)然后通过该账户类来实例化一个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 类中加入下面的属性:

public IQueryable<CustomerInfo> CustomerInfo

        {

            get

            {

                return CreateQuery<CustomerInfo>("CustomerInfo");

            }

        }

 

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

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

还有需要注意的地方是PartitionKey和RowKey。这两项共同组合成表的主键。详细信息可以参考MSDN:

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

步骤五:运行程序

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

阅读(828) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~