Azure Storage 系列(四)在.Net 上使用Table Storage

一,引言

  今天咱們就很少說廢話了,直接進入正題,Azure Table Storage。開始內容以前,咱們先介紹一下Azure Table Storage.html

  1,什麼是Azure Table Storagegit

  答:Azure Table Storage 是存儲結構化的 NoSql 數據的服務,經過無架構設計提供鍵/屬性存儲。 由於表存儲無架構,所以能夠很容易地隨着應用程序需求的發展使數據適應存儲。 對於許多類型的應用程序來講,訪問表存儲數據速度快且經濟高效,在數據量類似的狀況下,其成本一般比傳統 SQL 要低(官方解釋)。簡單來講,Azure  Table Srorage 能夠直接將實體,實體對象存入表結構中,和通常的關係型數據庫的 Table 很像,包含了列名和行數據,可是它不能提供像SQL中 inner join 方法,也是不能管理 Foreign Key。github

--------------------我是分割線--------------------數據庫

Azure Blob Storage 存儲系列:bash

1,Azure Storage 系列(一)入門簡介架構

2,Azure Storage 系列(二) .NET Core Web 項目中操做 Blob 存儲async

3,Azure Storage 系列(三)Blob 參數設置說明ide

4,Azure Storage 系列(四)在.Net 上使用Table Storage 工具

二,正文

1,添加對 Table Storage 的 「增,刪,改,查」 方法

1.1,安裝 Azure.TableStorage 相關的 Nuget 包,

NuGet:WindowsAzure.Storage(此包已被啓用,推薦使用 「Microsoft.Azure.Cosmos.Table」,今天做爲演示,就暫時使用當前已經遺棄的包post

Install-Package WindowsAzure.Storage -Version 9.3.3

從9.4.0版本開始,此庫已分爲多個部分並被替換。你們能夠經過當前連接進行查看當前庫的狀態:https://www.nuget.org/packages/WindowsAzure.Storage

1.2,建立 ITableService 接口,和 TableService 實現類,以及新增相應的對 Table 操做的方法

 添加Table數據操做

public async Task AddEntity(UserInfo user)
{
    var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
    var cloudTable = cloudTableClient.GetTableReference("USERINFO");
    await cloudTable.CreateIfNotExistsAsync();

    var tableOperation = TableOperation.Insert(user);
    await cloudTable.ExecuteAsync(tableOperation);
}

批量添加 Table 表數據

public async Task BatchAddEntities(List<UserInfo> users)
{
    var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
    var cloudTable = cloudTableClient.GetTableReference("USERINFO");
    await cloudTable.CreateIfNotExistsAsync();

    var tableBatchOperation = new TableBatchOperation();
    foreach (UserInfo item in users)
    {
         tableBatchOperation.Insert(item);
    }

    await cloudTable.ExecuteBatchAsync(tableBatchOperation);
 }

修改 Table 表數據

public async Task UpdateEntity(UserInfo user)
{
   var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
   var cloudTable = cloudTableClient.GetTableReference("USERINFO");

   var queryOperation = TableOperation.Retrieve<UserInfo>(user.PartitionKey, user.RowKey);

   var tableResult = await cloudTable.ExecuteAsync(queryOperation);
   if (tableResult.Result is UserInfo userInfo)
   {
        user.ETag = userInfo.ETag;
        var deleteOperation = TableOperation.Replace(user);
        await cloudTable.ExecuteAsync(deleteOperation);
   }
}

查詢Table 表數據

public async IAsyncEnumerable<UserInfo> QueryUsers(string filter)
{
    var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
    var cloudTable = cloudTableClient.GetTableReference("USERINFO");

    TableQuery<UserInfo> query = new TableQuery<UserInfo>().Where(filter);

    var users = await cloudTable.ExecuteQuerySegmentedAsync<UserInfo>(query, null);
    foreach (var item in users)
    {
        yield return item;
    }
}

刪除 Table 表數據

public async Task DeleteEntity(UserInfo user)
{
    var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
    var cloudTable = cloudTableClient.GetTableReference("USERINFO");

    var queryOperation = TableOperation.Retrieve<UserInfo>(user.PartitionKey, user.RowKey);

    var tableResult = await cloudTable.ExecuteAsync(queryOperation);
    if (tableResult.Result is UserInfo userInfo)
    {
        var deleteOperation = TableOperation.Delete(userInfo);
        await cloudTable.ExecuteAsync(deleteOperation);
     }
 }

刪除 Table 表

public async Task DeleteTable(string tableName)
{
    var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
    var cloudTable = cloudTableClient.GetTableReference(tableName);
    await cloudTable.DeleteIfExistsAsync();
 }

1.3,添加對 TableService ,CloudStorageAccount 的注入

services.AddSingleton(x => new CloudStorageAccount(new StorageCredentials("cnbateblogaccount", "FU01h022mn1JjONp+ta0DAXOO7ThK3diYhsdsdm0Hpg891n9nycsTLGZF83nJpGvTIZvsdsdVCVFhGOfV0wndOOQ=="), true));
services.AddSingleton<ITableService, TableService>();

完整代碼

  1 public class TableService : ITableService
  2     {
  3         private readonly CloudStorageAccount _cloudStorageClient;
  4         public TableService(CloudStorageAccount cloudStorageClient)
  5         {
  6             _cloudStorageClient = cloudStorageClient;
  7         }
  8 
  9         #region 01,添加表數據+async Task AddEntity(UserInfo user)
 10         /// <summary>
 11         /// 添加表數據
 12         /// </summary>
 13         /// <param name="user">用戶數據</param>
 14         /// <returns></returns>
 15         public async Task AddEntity(UserInfo user)
 16         {
 17             var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
 18             var cloudTable = cloudTableClient.GetTableReference("USERINFO");
 19             await cloudTable.CreateIfNotExistsAsync();
 20 
 21             var tableOperation = TableOperation.Insert(user);
 22             await cloudTable.ExecuteAsync(tableOperation);
 23         }
 24         #endregion
 25 
 26         #region 02,批量添加用戶表數據+async Task BatchAddEntities(List<UserInfo> users)
 27         /// <summary>
 28         /// 批量添加用戶表數據
 29         /// </summary>
 30         /// <param name="users">用戶數據</param>
 31         /// <returns></returns>
 32         public async Task BatchAddEntities(List<UserInfo> users)
 33         {
 34             var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
 35             var cloudTable = cloudTableClient.GetTableReference("USERINFO");
 36             await cloudTable.CreateIfNotExistsAsync();
 37 
 38             var tableBatchOperation = new TableBatchOperation();
 39             foreach (UserInfo item in users)
 40             {
 41                 tableBatchOperation.Insert(item);
 42             }
 43 
 44             await cloudTable.ExecuteBatchAsync(tableBatchOperation);
 45         }
 46         #endregion
 47 
 48         #region 03,刪除表操做根據表名+async Task DeleteTable(string tableName)
 49         /// <summary>
 50         /// 刪除表操做根據表名
 51         /// </summary>
 52         /// <param name="tableName">表命</param>
 53         /// <returns></returns>
 54         public async Task DeleteTable(string tableName)
 55         {
 56             var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
 57             var cloudTable = cloudTableClient.GetTableReference(tableName);
 58             await cloudTable.DeleteIfExistsAsync();
 59         }
 60         #endregion
 61 
 62         #region 04,刪除用戶數據根據用戶條件+async Task DeleteEntity(UserInfo user)
 63         /// <summary>
 64         /// 刪除用戶數據根據用戶條件
 65         /// </summary>
 66         /// <param name="user">用戶條件</param>
 67         /// <returns></returns>
 68         public async Task DeleteEntity(UserInfo user)
 69         {
 70             var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
 71             var cloudTable = cloudTableClient.GetTableReference("USERINFO");
 72 
 73             var queryOperation = TableOperation.Retrieve<UserInfo>(user.PartitionKey, user.RowKey);
 74 
 75             var tableResult = await cloudTable.ExecuteAsync(queryOperation);
 76             if (tableResult.Result is UserInfo userInfo)
 77             {
 78                 var deleteOperation = TableOperation.Delete(userInfo);
 79                 await cloudTable.ExecuteAsync(deleteOperation);
 80             }
 81         }
 82         #endregion
 83 
 84         #region 05,查詢用戶根據條件+async IAsyncEnumerable<UserInfo> QueryUsers(string filter)
 85         /// <summary>
 86         /// 查詢用戶根據條件
 87         /// </summary>
 88         /// <param name="filter">條件</param>
 89         /// <returns></returns>
 90         public async IAsyncEnumerable<UserInfo> QueryUsers(string filter)
 91         {
 92             var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
 93             var cloudTable = cloudTableClient.GetTableReference("USERINFO");
 94 
 95             TableQuery<UserInfo> query = new TableQuery<UserInfo>().Where(filter);
 96 
 97             var users = await cloudTable.ExecuteQuerySegmentedAsync<UserInfo>(query, null);
 98             foreach (var item in users)
 99             {
100                 yield return item;
101             }
102         }
103         #endregion
104 
105         #region 06,更新用戶表數據根據新的用戶數據+async Task UpdateEntity(UserInfo user)
106         /// <summary>
107         /// 更新用戶表數據根據新的用戶數據
108         /// </summary>
109         /// <param name="user">新用戶數據</param>
110         /// <returns></returns>
111         public async Task UpdateEntity(UserInfo user)
112         {
113             var cloudTableClient = _cloudStorageClient.CreateCloudTableClient();
114             var cloudTable = cloudTableClient.GetTableReference("USERINFO");
115 
116             var queryOperation = TableOperation.Retrieve<UserInfo>(user.PartitionKey, user.RowKey);
117 
118             var tableResult = await cloudTable.ExecuteAsync(queryOperation);
119             if (tableResult.Result is UserInfo userInfo)
120             {
121                 user.ETag = userInfo.ETag;
122                 var deleteOperation = TableOperation.Replace(user);
123                 await cloudTable.ExecuteAsync(deleteOperation);
124             }
125         } 
126         #endregion
127     }
TableService.cs
 1 public interface ITableService
 2     {
 3         Task AddEntity(UserInfo user);
 4 
 5         Task BatchAddEntities(List<UserInfo> users);
 6 
 7         IAsyncEnumerable<UserInfo> QueryUsers(string filter);
 8 
 9         Task UpdateEntity(UserInfo user);
10 
11         Task DeleteEntity(UserInfo user);
12 
13         Task DeleteTable(string tableName);
14 
15     }
ITableService.cs
 1 [Route("Table")]
 2     public class TableExplorerController : Controller
 3     {
 4         private readonly ITableService _tableService;
 5 
 6         public TableExplorerController(ITableService tableService)
 7         {
 8             this._tableService = tableService;
 9         }
10 
11         [HttpPost("AddUser")]
12         public async Task<ActionResult> AddEntity([FromBody]UserInfo user)
13         {
14             await _tableService.AddEntity(new UserInfo("zhangsan", "610124199012223650") { Email = "135012689@qq.com", TelNum = "13000000000" });
15             return Ok();
16         }
17 
18         [HttpPost("AddBatchUser")]
19         public async Task<ActionResult> AddEntities([FromBody]List<UserInfo> users)
20         {
21             List<UserInfo> userList = new List<UserInfo>();
22             userList.Add(new UserInfo("lisi", "610124199012223651") { Email = "1350126740@qq.com", TelNum = "13000000001" });
23             userList.Add(new UserInfo("lisi", "610124199012223652") { Email = "1350126741@qq.com", TelNum = "13000000002" });
24             userList.Add(new UserInfo("lisi", "610124199012223653") { Email = "1350126742@qq.com", TelNum = "13000000003" });
25             await _tableService.BatchAddEntities(userList);
26             return Ok();
27         }
28 
29         [HttpGet("Users")]
30         public ActionResult QueryUsers()
31         {
32             var filter = TableQuery.CombineFilters(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "zhangsan"), TableOperators.And, TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, "610124199012223650"));
33 
34             return Ok(_tableService.QueryUsers(filter));
35         }
36 
37         [HttpPut("UpdateUser")]
38         public async Task<ActionResult> UpdateUser([FromBody]UserInfo user)
39         {
40             await _tableService.UpdateEntity(new UserInfo("zhangsan", "610124199012223650") { Email = "135012689@qq.com", TelNum = "15000000000" });
41             return Ok();
42         }
43 
44         [HttpDelete("DeleteEntity")]
45         public async Task<ActionResult> DeleteEntity([FromBody]UserInfo user)
46         {
47             await _tableService.DeleteEntity(new UserInfo("lisi", "610124199012223651"));
48             return Ok();
49         }
50 
51         [HttpDelete("{tableName}")]
52         public async Task<ActionResult> DeleteTable(string tableName)
53         {
54             await _tableService.DeleteTable(tableName);
55             return Ok();
56         }
57     }
TableExplorerController.cs
 1 public class UserInfo:TableEntity
 2     {
 3         public UserInfo()
 4         {
 5 
 6         }
 7 
 8         public UserInfo(string userName, string IdCardNum)
 9         {
10             this.PartitionKey = userName;
11             this.RowKey = IdCardNum;
12 
13         }
14 
15         public string Email { get; set; }
16 
17         public string TelNum { get; set; }
18     }
UserInfo.cs

2,運行項目,經過接口方式調用是否能夠對 Table 表數據進行操做

2.1 添加用戶數據

咱們在 postman 中調用添加用戶表數據接口(控制器中默認構造了用戶信息,因此我這邊沒有在Body中添加參數)

咱們能夠看到,在Azure Portal 上已經建立出一個叫 「USERINFO」 的表信息(注意,你們不要疑惑,能夠看看上面添加用戶的Service方法,我這裏有兩行代碼)

var cloudTable = cloudTableClient.GetTableReference("USERINFO");
await cloudTable.CreateIfNotExistsAsync();

獲取 「USERINFO」 表的引用實例,若是當前實例不存儲就建立 「USERINFO」 表

接下來,咱們看看 "USERINFO" 表中剛剛添加進去的數據,這時候咱們就要藉助 VS 的 "Cloud Expoere「 的工具了

VS 點擊 」視圖=》Cloud Expoere「

點擊當前 」帳號管理「 找到與之對應的本身的Azure 訂閱相關聯的帳號

點擊 」cnbateblogaccount「 的 Azure Storage 帳號,找到剛剛建立好的 」USERINFO「 Azure Table,右鍵點擊」打開「

咱們能夠看到添加到 」USERINFO「 表中的數據 (注意,Timestamp字段的時間問題,這裏是由於Azure Table Storage 採用的是標準時間,換算到中國時間 就得在原有時間基礎上+8)

 2.2 批量添加用戶數據

注意:批量添加 Table 數據的話,這些批量數據的 「PartitionKey」 必須是相同的

輸入批量添加用戶數據的連接,點擊 「Send」

 

 咱們繼續回到 VS 的Cloud Explorer 查看 「USERINFO」 Table 的表信息

額外話題,剛纔提到批量添加 Table 表數據,有提到這些數據的 「PartitionKey」 必須一致。Azure Table Storage 對批處理操做作了一些限制

  1,單個批處理中的全部實體必須具備相同的分區鍵

  2,單個批處理操做只能包含100個實體。

3,查詢用戶數據

注意,我這裏使用兩個查詢條件聯合進行查詢,分別是 「PartitionKey」 和 「RowKey」 做爲查詢的 Key,經過 「Partition」 等於 「zhangsan」 和 「RowKey」 等於 「610124199012113650」 

輸入查詢用戶表數據接口,點擊 「Send」 進行調用接口

同時,咱們能夠看到將查詢條件對應的數據查詢出來了

 4,更新表數據

注意,目前的更新操做時根據 「PartitionKey」 和 「RowKey」 進行檢索數據,將新的用戶數據進行替換操做,記得將舊的表數據中的 「ETag 也要進行賦值到新的對象中,再執行替換操做

注意,咱們此時更新操做主要更新的是 「TelNum」 字段

 輸入查詢用戶表數據接口,點擊 「Send」 進行調用接口,返回狀態碼 200

同時咱們再刷新 Table 中的數據,成功的 PartitionKey 等於 「zhangsan」,RowKey 等於 「610124199012223650」 的數據的 TelNum 從 13000000000 改成 「15000000000」

5,刪除 Table 表數據

咱們嘗試刪除 「PartitionKey」 等於 「lisi」,「RowKey」 等於 「610124199012223651」的數據

 也是根據條件先查詢到當前數據,再判斷是否存儲,若是存在 就執行刪除操做

在 postman 輸入刪除實體操做的接口連接,而後點擊 「Sand」

 接下來,咱們繼續查看當前 Table 中的數據,以及沒有  「PartitionKey」 等於 「lisi」,「RowKey」 等於 「610124199012223651」的數據了。

6,刪除 Table 表

接下來,咱們就要將整個 "SUERINFO" 表刪除的操做

 繼續在 postman 上調用刪除 Table 操做的接口地址

當前 Table Storage 已經找不到 「USERINFO」 的 Table 信息了

 咱們再上Azue Portal 上找一找,看看是否把 「USERINFO」 表刪除了

對應的 cnbatebogaccount 存儲帳戶下的 Tables 中已經沒有了任何表了

OK,今天的分享到此結束,撒花🎉🎉🎉🎉🎉🎉!

三,結尾

  今天,咱們經過代碼(已遺棄的類庫)演示了一下如何操做 Tables 數據,已經建立/刪除 Table,下一篇繼續講解 Table 是若是進行操做的,可是會換一套微軟推薦的 「Microsoft.Azure.Cosmos.Table」,咱們也要跟上微軟的腳步,與時俱進。

github:https://github.com/yunqian44/Azure.Storage.git

做者:Allen 

版權:轉載請在文章明顯位置註明做者及出處。如發現錯誤,歡迎批評指正。

相關文章
相關標籤/搜索