以前在用的 Azure 儲存體,再過不久就要停止服務了,取而代之的是 Azure Cosmos DB,不過在開服務時依然是稱之為儲存體,只是選項上會讓你選擇是 SQL、NoSQL 還是 Table。因為觀念上還是習慣 Table,所以最近研究的是這塊,在做 side project 時也比較好上手。

使用 Table 前,要先定義 Table 上所放的資料,另外別忘了安裝 Azure.Data.Tables 套件:

public record AzureTestData : ITableEntity
{
    public string RowKey { get; set; } = Guid.NewGuid().ToString();

    public string PartitionKey { get; set; } = "AzureTestData";

    public ETag ETag { get; set; } = default!;

    public DateTimeOffset? Timestamp { get; set; } = default!;

    public string Name { get; init; } = default!;

    public int Age { get; init; }

    public string Desc { get; init; } = string.Empty;
}

因為 Table 上其實是可以放不同種類的資料,所以邏輯上會用 PartitionKey 來做區別,這邊為了方便所以是直接寫在 record 裡,這樣在其它的程式碼就不用去設定 PartiotnKey,但還是以實際情況為主。

接下來示範怎麼塞資料,首先是取得可以操作 table 的 client:

TableServiceClient tableServiceClient = new TableServiceClient(_connectionString);
TableClient tableClient = tableServiceClient.GetTableClient(tableName: _tableName);
tableClient.CreateIfNotExistsAsync().Wait();
_cosmosClient = tableClient;

這裡要做的就是設定連線字串跟設定 table name,而塞資料的方式就只要呼叫 await _cosmosClient.AddEntityAsync<AzureTestData>(data); 即可,而拿資料則所是 _cosmosClient.Query<AzureTestData>(x => x.PartitionKey == "AzureTestData").ToList();

完整的程式碼如下:

public class AzureDataRepository : IDataRepository
{
    private readonly string _tableName = "AzureTestTable";

    private readonly string _connectionString = string.Empty;

    private TableClient _cosmosClient;

    public AzureDataRepository()
    {
        Init();
    }

    public AzureDataRepository(string connectionString)
    {
        _connectionString = connectionString;
        Init();
    }

    private void Init()
    {
        TableServiceClient tableServiceClient = new TableServiceClient(_connectionString);
        TableClient tableClient = tableServiceClient.GetTableClient(tableName: _tableName);

        tableClient.CreateIfNotExistsAsync().Wait();
        _cosmosClient = tableClient;
    }

    public List<AzureTestData> GetAzureTestDatas()
    {
        var azureTestDatas = _cosmosClient.Query<AzureTestData>(x => x.PartitionKey == "AzureTestData");
        return azureTestDatas.ToList();
    }

    public async Task AddData(AzureTestData data) 
    {
        await _cosmosClient.AddEntityAsync<AzureTestData>(data);
    }
}

在 ASP.NET 中,因為都是用 DI,所以可以這樣設定:builder.Services.AddSingleton(typeof(AzureDataRepository), new AzureDataRepository(connectionstring));

參考資料