一,引言
今天我們就不多說廢話了,直接進入正題,Azure Table Storage。開始內容之前,我們先介紹一下Azure Table Storage.
1,什么是Azure Table Storage
答:Azure Table Storage 是存儲結構化的 NoSql 數據的服務,通過無架構設計提供鍵/屬性存儲。 因為表存儲無架構,因此可以很容易地隨着應用程序需求的發展使數據適應存儲。 對於許多類型的應用程序來說,訪問表存儲數據速度快且經濟高效,在數據量相似的情況下,其成本通常比傳統 SQL 要低(官方解釋)。簡單來說,Azure Table Srorage 可以直接將實體,實體對象存入表結構中,和一般的關系型數據庫的 Table 很像,包含了列名和行數據,但是它不能提供像SQL中 inner join 方法,也是不能管理 Foreign Key。
--------------------我是分割線--------------------
Azure Blob Storage 存儲系列:
2,Azure Storage 系列(二) .NET Core Web 項目中操作 Blob 存儲
3,Azure Storage 系列(三)Blob 參數設置說明
4,Azure Storage 系列(四)在.Net 上使用Table Storage
5,Azure Storage 系列(五)通過Azure.Cosmos.Table 類庫在.Net 上使用 Table Storage
6,Azure Storage 系列(六)使用Azure Queue Storage
二,正文
1,添加對 Table Storage 的 “增,刪,改,查” 方法
1.1,安裝 Azure.TableStorage 相關的 Nuget 包,
NuGet:WindowsAzure.Storage(此包已被棄用,推薦使用 “Microsoft.Azure.Cosmos.Table”,今天作為演示,就暫時使用當前已經遺棄的包)
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 }

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 }

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 }

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 }
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
版權:轉載請在文章明顯位置注明作者及出處。如發現錯誤,歡迎批評指正。